FlutterでREST APIを叩いて取得したデータを表示してみた
こんにちは、CX事業本部IoT事業部の高橋雄大です。
REST API(RESTful API)を利用してデータの取得と表示をやってみたいと思います。今回はまずAPIのリクエスト方法を学習したいので、例外処理やModelの実装はしていません。Flutterの公式ドキュメントに沿ったシンプルな方法で実装していきます。
本記事のゴール
Google Books APIを利用してブックリストを表示します。
環境情報
項目 | 内容 |
---|---|
OS | macOS Monterey 12.3 (21E230) |
Visual Studio Code | 1.66.0 |
Xcode | 13.3 (13E113) |
Flutter | 2.10.4 |
Dart | 2.16.2 |
ブックリストを実装
HTTPリクエストに必要なhttpパッケージをFlutterのプロジェクトへ追加します。
flutter pub add http
main.dart
でブックリストを実装します。
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MaterialApp( title: 'Flutter Sample', home: MyHomePage(title: 'Flutter Sample'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List items = []; Future<void> getData() async { var response = await http.get(Uri.https( 'www.googleapis.com', '/books/v1/volumes', {'q': '{Flutter}', 'maxResults': '40', 'langRestrict': 'ja'})); var jsonResponse = jsonDecode(response.body); setState(() { items = jsonResponse['items']; }); } @override void initState() { super.initState(); getData(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Flutter Sample'), ), body: ListView.builder( itemCount: items.length, itemBuilder: (BuildContext context, int index) { return Card( child: Column( children: <Widget>[ ListTile( leading: Image.network( items[index]['volumeInfo']['imageLinks']['thumbnail'], ), title: Text(items[index]['volumeInfo']['title']), subtitle: Text(items[index]['volumeInfo']['publishedDate']), ), ], ), ); }, ), ); } }
解説
Future
で非同期処理にして、StatefulWidget
のsetState
でデータを更新&画面の再描写を実現しています。
class _MyHomePageState extends State<MyHomePage> { List items = []; Future<void> getData() async { var response = await http.get(Uri.https( 'www.googleapis.com', '/books/v1/volumes', {'q': '{Flutter}', 'maxResults': '40', 'langRestrict': 'ja'})); var jsonResponse = jsonDecode(response.body); setState(() { items = jsonResponse['items']; }); }
ListView.builder
でリストを生成して、その中にCard
を作成しています。カード内では取得した本の情報を出力しています。
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Flutter Sample'), ), body: ListView.builder( itemCount: items.length, itemBuilder: (BuildContext context, int index) { return Card( child: Column( children: <Widget>[ ListTile( leading: Image.network( items[index]['volumeInfo']['imageLinks']['thumbnail'], ), title: Text(items[index]['volumeInfo']['title']), subtitle: Text(items[index]['volumeInfo']['publishedDate']), ), ], ), ); }, ), ); } }
動作確認
画像付きのブックリストが表示されることを確認できました。
まとめ
HTTPリクエスト自体はとても簡単に実装することができました。画面の描写について、取得したデータを変数へ直接代入すると再描写がされませんでした。画面を再描写するにはStatefulWidget
のsetState
で状態を更新しなければならないので、慣れていない場合には注意が必要です。