FlutterでAPIから受け取ったデータリストを表示させる
Flutter で API から受け取ったデータについて、データ 1 つだけでなくリストだった場合どう書けばいいのかで少し悩んだので備忘録として残しておきます。
今回記事で記載したアプリはGitHubに転がしています。
動作環境
Macbook Pro M1 2020 / macOS 13.6
今回使った API
お馴染み JSONPlaceholder からposts
API を使用しました。
https://jsonplaceholder.typicode.com/posts
手順
1. リストの class と fetch メソッドを準備
まず API から返却されるデータの class(今回だとPost
クラス)を作成します。
書き方についてはここを参考に API のレスポンスに合わせて作成すれば OK。
fetch メソッドはこんな形で作成できます。
Future<List<Post>> fetchPosts() async { final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts')); final List<dynamic> jsonData = jsonDecode(response.body); if (response.statusCode == 200) { return jsonData.map((dynamic item) => Post.fromJson(item)).toList(); } else { throw Exception('Failed to load Posts'); }}
2. アプリを立ち上げたときに state に API から返却されるリストをセットする
表示する Widget が StatefullWidget
になっていることを確認してからState
に以下のコードを追加させます。
state 値は非同期に代入させたいので、late に設定させています。
そしてinitState
イベントでアプリが立ち上がったタイミングで 1 で作成した fetch メソッドを使い、state 値 に API のレスポンスをセットさせます。
これで state にレスポンスを持たせることが出来ました。
class _MyAppState extends State<MyApp> { late Future<List<Post>> futurePosts;
@override void initState() { super.initState(); futurePosts = fetchPosts(); } ...}
3. API から返却されるリストを画面に表示させる
FutureBuilder Widget を使うことで API の読み込み中・読み込み完了時の処理を簡単に記載する事ができます。 今回は、
- API の読み込み中 -> CircularProgressIndicator Widget を使ってローディングを出しておく
- API の読み込み完了 -> ListView Widget で API で取ったリストを表示
なお ListView での表示は、FutureBuilder から取れるsnapshot.data
に API から取得したリストが入っているため、これを使うことで実現できます。
サンプルアプリではこんな感じで記載しました。
body: Center( child: FutureBuilder( future: futurePosts, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), child: Container( decoration: BoxDecoration( color: Colors.grey[300], ), child: ListTile( title: Text(snapshot.data![index].title), subtitle: Text(snapshot.data![index].body), ), ), ); }); } else { return const Center(child: CircularProgressIndicator()); } }, ),)