はじめに
FlutterでAPIからデータ取得して、リスト表示するサンプルを作成しました。
FlutterでAPIをコールしてデータを表示して見た
この記事見て、自分もFlutterで同様のやつを作成したかったので、
いろいろ調べた結果をQiitaにのっけときます。
今回つくるもの
![Screenshot_20181014-015712 (3).png](https://qiita-image-store.s3.amazonaws.com/0/190712/b04ef3da-673f-2c3b-cb0e-a0ce24564ac3.png)!
初心者向けに(自分もflutter初心者なので)段階を追ってかきたい。
つくろう
1.必要モジュールのインポート
main.dart
import 'package:flutter/material.dart'; //google提供のUIデザイン
import 'package:http/http.dart' as http; //httpリクエスト用
import 'dart:async'; //非同期処理用
import 'dart:convert'; //httpレスポンスをJSON形式に変換用
モジュールについて
[material.dart](https://docs.flutter.io/flutter/material/material-library.html) Google公式のデザインパッケージ。flutterプロジェクト基本いれる。 [http.dart](https://pub.dartlang.org/packages/http) HTTPリクエスト用.公式ドキュメントでも as httpとして使用してい。 [async](https://www.dartlang.org/articles/language/await-async) JavaScriptのPromise。SwiftのSwiftTask。非同期処理 [convert](https://api.dartlang.org/stable/2.0.0/dart-convert/dart-convert-library.html) Jsonのエンコーダー、デコーダー。2.メイン関数のとアプリのひな型を作る
void main() { // main.dartは基本これだけを呼ぶ
runApp(MaterialApp( // runAppにはStatelessWidget or StatefullWidgetを継承したものを渡す
home: HomePage(), //homeで、ルーティング情報ここにかいてく。
));
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(); //Scaffold() アプリの中身(appbar+title構造)を簡単につくれる
}
}
メイン関数とその後の動きについて
run main.dart -> main() -> runApp() -> home: -> (state情報みる)HomePage -> (state継承した)_HomePageState() -> build() (Widgetはbuild()をもっている) Dartの状態遷移は以下の記事参照 [Flutterアプリの基本](https://issus.me/projects/1520/issues/2)/[Flutterの状態遷移について](https://qiita.com/tatsu/items/38cd85efd93005b95af9) Dartのstatefull,statelessについては以下参照 [statefull,statelessについて(日本語)](https://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/stateful-and-stateless/)/[statefull,statelessについて(英語)](https://stackoverflow.com/questions/47501710/what-is-the-relation-between-stateful-and-stateless-widgets-in-flutter) 状態変化に応じて変わるor変わらないこと。 上記のふるまいがアプリ起動時の基本形でありひな型部分。 Widget build()の内部にゴリゴリとデザインとアクションを書き込んでいくこと。 Scaffold()が簡単に書くために用意されてるのでつかう。3.タイトルバーと背景色つける
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("あああああ"),
backgroundColor: Colors.green,
),
);
}
Scaffold,appBarについて
[Scaffold_class](https://docs.flutter.io/flutter/material/Scaffold-class.html) [Scaffold_samples](https://flutter.io/catalog/samples/Scaffold_index/) class:Implements the basic material design visual layout structure. description:A typical AppBar with a title, actions, and an overflow dropdown menu. scaffold()は、バー、タイトル、中身、アクション、ボトムの典型的なアプリ構造を簡単にできる仕組みらしい。詳しくはSamplesリンクをみるとわかります。 [appBar](https://flutter.io/catalog/samples/basic-app-bar/) ![basic_app_bar_small.png](https://qiita-image-store.s3.amazonaws.com/0/190712/fa798028-19a1-a423-5990-410cee9522e5.png) タイトル、ボタンとかをおく。ボタンには(画像みたいに)アクションとか置いてくのが典型的な仕組み。 今回は置かないで、テキストと背景色をつけるだけ。 ### 3.2ここまででできるやつ
![Screenshot_20181014-015712 (4).png](https://qiita-image-store.s3.amazonaws.com/0/190712/1169b116-6f1c-3d9a-4df2-9af2faade58c.png)
4.APIデータを用意する
どこでもいいですが、サンプルページREQ | RESにある、
以下のデータをつかわせていただく。
{
"page": 2,
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 4,
"first_name": "Eve",
"last_name": "Holt",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
},
{
"id": 5,
"first_name": "Charles",
"last_name": "Morris",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
},
{
"id": 6,
"first_name": "Tracey",
"last_name": "Ramos",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
}
]
}
使用するurlは以下です。
url_for_request
https://reqres.in/api/users?page=2
5.非同期操作とか
//class _HomePageState extends State<HomePage> {
Future getData() async{ //Future xxx async{} という記法
http.Responsde response = await http.get("https://reqres.in/api/users?page=2");
}
// 非同期処理は、デフォルトでは呼び出し元は処理の完了を待ちませんが、
// await キーワードをつけると完了を待つことができる。
@override
void initState() {
super.initState();
getData();
}
[async_公式](https://www.dartlang.org/tutorials/language/futures)/[async_日本語](https://blog.chocolapod.net/momokan/entry/104)
非同期処理:処理が呼び出されつつも、呼び出し元では完了を待たずにその先に処理が進んでいくこと。
[initState_method](https://docs.flutter.io/flutter/widgets/State/initState.html)/[widget lifecycle events](https://flutter.io/widgets-intro/#responding-to-widget-lifecycle-events)
initStateは、viewのライフライクル的に言えば、Stateオブジェクトがつくられてから"一度"呼ばれるらしい。
呼ばれるタイミングと頻度は重要。ライフサイクルは要復習。
6.データ変換:JSON->Map and List
//class _HomePageState extends State<HomePage> {
Map data;
List useData;
// Future getData() async{
// http.Responsde response = await http.get("");
data = json.decode(response.body); //json->Mapオブジェクトに格納
setState(() { //状態が変化した場合によばれる
userData = data["data"]; //Map->Listに必要な情報だけ格納
});
}
[Flutterアプリの基本](https://issus.me/projects/1520/issues/2)/[FlutterのStateについて](http://mashi.exciton.jp/archives/268)
変数を用意して、取得したデータを順次処理していく段階。
json->Map->List。
7.1 画面に表示させる-プロフィール画像
// appBar: AppBar(
// title: Text("あああああああ"),
// backgroundColor: Colors.green,
// ),
body: ListView.builder( //スクロール可能な可変リストを作る
itemCount: userData == null ? 0 : userData.length, //受け取る数の定義
itemBuilder: (BuildContext context, int index) { //ここに表示したい内容をindexに応じて
return Card( //cardデザインを定義:material_design
child: Row(
children: <Widget>[
CircleAvatar( //ユーザプロフィール画像に使う用のクラス
backgroundImage: NetworkImage(userData[index]["avator"]),
//NetworkImage()はHTTPで画像をとってくる。これはプロフィール画像。
)
],
),
);
},
)
[ListView.builder_const](https://docs.flutter.io/flutter/widgets/ListView/ListView.builder.html)/[リストを表示する](https://nzigen.com/flutter-reference/2018-04-17-list-view.html)
ListView.builder:countとbuilderで、値の数だけ柔軟に生成できるリスト構造
[Flutterでよくつかう共通Widget
](https://qiita.com/konifar/items/1136dd1d69ed0895b6d5)/[Card_class](https://docs.flutter.io/flutter/material/Card-class.html)
card:以下のような、よく使われる共通デザインのこと。
![card.png](https://qiita-image-store.s3.amazonaws.com/0/190712/fc9370b8-100b-98d3-5fbe-b5c237441caa.png)
[CircleAvator_class](https://docs.flutter.io/flutter/material/CircleAvatar-class.html)/[githubアプリ](https://qiita.com/rkowase/items/56f6606b7e101d939e10)
CircleAvator->NetworkImageというプロフィール画像を表示するテンプレの実装
### 7.2 画面に表示させる-テキスト
```dart
// CircleAvatar(
// backgroundImage: NetworkImage(userData[index]["avator"]),
// ),
Text("${userData[index]["first_name"]} ${userData[index]["last_name"]}")
```
あとはpaddingとかをちょうせつしたら完成します!
あとがき
flutterは公式ドキュメントがかなり充実しているので大助かり。
あと、英語力がないと積むのだけ注意。