1. 概要
上記記事で作成したAPIにアクセスしてJSONデータを取得し、スマホ画面に表示してみます。
- Windows11
- Flutter
- AndroidManifest.xml
- パーミッションを追加
- android.permission.INTERNET
- パーミッションを追加
- 依存ライブラリーを追加
- http
- Visual Studio Code
- 「localhost」注意
- 起動
- スマホアプリ
対象としては開発を1年程やってて自分で最初から開発してみたい方になります。そのため細かい用語などの説明はしません。

2. プロジェクトを作成
2-1. こちらを参考
3. http(Dependencies)追加
3-1. こちらを参考
flutter pub add http



4. パーミッションを設定
4-1. Androidのマニフェストファイルにパーミッションを設定
- <プロジェクト名>/android/app/src/main/AndroidManifest.xml
<!-- Required to fetch data from the internet. -->
<uses-permission android:name="android.permission.INTERNET" />

5. モデルクラスを作成
5-1. <プロジェクト名>/lib/model/user.dart
import 'dart:convert';
class User {
final int id;
final String name;
final String email;
User({
required this.id,
required this.name,
required this.email,
});
factory User.fromJson(Map<String, dynamic> json) => User(
id: json["id"],
name: json["name"],
email: json["email"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"email": email,
};
}
User userModelFromJson(String str) => User.fromJson(json.decode(str));
String userModelToJson(User user) => json.encode(user.toJson());
6. サービスクラスを作成
6-1. <プロジェクト名>/lib/service/api_client.dart
import 'dart:convert';
import 'package:http_api/model/user.dart';
import 'package:http/http.dart' as http;
class ApiClient {
Future<List<User>?> fetchUsers() async {
final url = Uri.parse('http://123.45.678.9:8080/userList');
try {
final response = await http.get(url);
if (response.statusCode == 200) {
final List<dynamic> body = jsonDecode(response.body);
final List<User> users =
body.map((dynamic user) => User.fromJson(user)).toList();
return users;
} else {
return null;
}
} catch (e) {
// ignore: avoid_print
print(e.toString());
}
return null;
}
}
- localhostにアクセス時の注意
- URLのIP指定(localhostや127.0.0.1ではない)
- ifconfig – eth0 – inetを指定
sondon@Sondon:~/dev/wsl$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 123.45.678.9 netmask 255.255.240.0 broadcast 123.45.678.255
inet6 abcd::efg:5dff:feaf:58ce prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:af:58:ce txqueuelen 1000 (Ethernet)
RX packets 188569 bytes 552152761 (552.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 72216 bytes 6516813 (6.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 91442 bytes 464428044 (464.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 91442 bytes 464428044 (464.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
7. レポジトリクラスを作成
7-1. <プロジェクト名>/lib/repository/user_repository.dart
import 'package:http_api/service/api_client.dart';
class UserRepository {
final apiClient = ApiClient();
dynamic fetchUsers() async {
return await apiClient.fetchUsers();
}
}
8. ビューモデルクラスを作成
8-1. <プロジェクト名>/lib/view_model/user_viewmodel.dart
import 'package:http_api/repository/user_repository.dart';
class UserViewModel {
final userRepository = UserRepository();
dynamic fetchUsers() async {
return await userRepository.fetchUsers();
}
}
9. ビュークラスを作成
9-1. <プロジェクト名>/lib/view/user_page.dart
import 'package:flutter/material.dart';
import '../model/user.dart';
import '../view_model/user_viewmodel.dart';
// ignore: must_be_immutable
class UserPage extends StatelessWidget {
UserPage({Key? key}) : super(key: key);
final UserViewModel userViewModel = UserViewModel();
List<User> users = [];
Future getUsers() async {
users = (await userViewModel.fetchUsers())!;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("User List"),
),
body: FutureBuilder(
future: getUsers(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: Text("LOADING"),
);
} else {
if (users.isEmpty) {
return const Center(
child: Text("NO DATA"),
);
}
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) => ListTile(
title: Text(users[index].name),
subtitle: Text(users[index].email),
),
);
}
},
),
);
}
}
10. メインクラスを修正
10-1. <プロジェクト名>/lib/main.dart
import 'package:flutter/material.dart';
import 'package:http_api/view/user_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Users',
theme: ThemeData(primarySwatch: Colors.lime),
home: UserPage(),
);
}
}
11. 結果
11-1. 結果

12. 参考
投稿者プロフィール

-
開発好きなシステムエンジニアです。
卓球にハマってます。
最新の投稿
【Next.js】2023年12月2日【NextJS】Local Storage
【Next.js】2023年12月2日【NextJS】Canvasを使い、図形を描画
【Next.js】2023年11月3日【NextJS】Error Handling
【Next.js】2023年10月21日【NextJS】Internationalization(i18n) – Localization