WebAPIと連携してフリー画像検索アプリ制作チュートリアルを学びました。備忘録です

下記動画を参考に作りました。

【Flutterの教科書】④ WebAPIと連携してフリー画像検索アプリを作ろう【前編】
https://youtu.be/vdYrRkgk20E?si=k6oBb9Z6caF_hQlV

目次に沿ってメモを残します。

■目次
00:00 前回までのおさらい
00:18 画像検索アプリの紹介
01:05 Flutterの教科書の紹介
01:45 WebAPI Pixabay の登録

## 03:15 サンプルURLから得られるJSONの解説
とりあえずkeyとvalueがセットになっていることをわかればいい
	
## 05:55 DartPadを使ってMapとListの使い方を解説
https://dartpad.dev/?
PixabayのサンプルURLを使ってMapとListの使い方
keyとvalueがセットになっていることをさきほど伝えました
MAPというのもまさにkeyとvalueのセットの型になっています。
<String, dynamic>と書いていますが、Stringの型で、dynamicがvalueの型になっています
JSONのkeyというのは必ずString型になることが決まっています。
Stringは必ず文字列だけど。dynamicはどんな方にもなりえますよ。というものです。なのでこの型っていうのが、数字担っていたり、配列になってたり、文字列だったりする。動的に変化しうるっていう場合は、このDynamicっていうのを使います。
JSONをdart内で扱うときは、とりあえずMap<String, dynamic>を使うんだなと今は覚えておけばいい。

totalの数字を取得する方法
これは恐らくintで取得できるので変数の型はint　totalという変数名に対して、このデータからこの数字を取り出したいときっていうの書き方がこういうふうになります。
```dart
int total = data['total'];
```
dataという変数名の[]この中のkeyを指定するとここのvalueが取り出せる（"total": 35467,の数字のところ）という仕組みになっています
これをコンソールでTotalをprintしてみます。print(total);
そうするとコンソール上で「35467」と表示されました。ちゃんと取得できました
この様にここでkeyを指定してvalueが取得できるというこの感覚を掴んでくれればOKです

次にhits　今度は単なる数字ではなく、リスト型が入っているっていうものについてもやっていきます
List hits = data['hits'];　リスト型なので、Listと書いてある
print(hits);同じくプリントすると横にうわーと取得してくれることがわかる
この一個のhitこれもMap<String, dynamic>になっています。
この1つ目の要素にアクセスするときに、どうすればいいかをやっていきます
これの型がまたMap<String, dynamic>なので、同じく書いて、関数名を決めて今回はfirsthitで
配列がですね、番号が振られていて、要素の数まで番号が振られています
番号は０始まりなのでそれを注意して
最初の要素にアクセスしたい場合はこの角括弧の中に、０というふうにいれてあげればOK
Map<String, dynamic> firsthit = hits[0];これで取れる。
１つ目の要素とは"hits": [{～},まで。１つ目の中かっこまでを言う。
②個めを取得したいならさきほどの「０」を「１」にすればいい

hitsのうち例えばpreviewURLだけを出力する場合は、

先ほど[0]を取得したあとはMAP型になっているので、printでpreviewURLを取得してあげればOKです
```dart
	Map<String, dynamic> firsthit = hits[0];
	print(firsthit['previewURL']);
```
今回抑えてほしいのはMAPの場合はこの角括弧の中にkeyを指定するとvalueが取り出せると
複数のデータが連なっているリスト型のデータの場合はここに数字を入れてあげるとその番号の要素を取り出せますよというところを覚えていただきたいです。これ今回多用していきますのでぜひ覚えていて下さい
だーとぱっどでやる作業はここまで
	
## 14:34 StatefulWidgetを追加して初回ビルド
NEW　Projectを立ち上げて、main.dart内を掃除して、StatelessWidget作って、MaterialAppまで書く
その次に下に、StatefulWidgetを作る。名前はPixabayPage
PixabayPageにはScaffoldだけ入れておきましょう
この状態で１回ビルドができるか確認しましょう
表示されない…MaterialApp内でPixabayPageをhomeで呼んでなかったのが原因
ちなみにScaffoldだけの状態は真っ白い画面が表示される
	
## 17:14 http通信のためのdioパッケージを追加
ターミナルからパッケージを追加していく
flutter pub add パッケージ名です
今回URLからデータを取得するときにhttp通信というのをやっていくんですが
そのためのパッケージとしてhttpというパッケージとdioというパッケージがあります
今回dioの法を使っていくのでflutter pub add dioというのでパッケージが追加できます
これをターミナルで実行する
パッケージを追加すると、ビルドを一旦閉じてもう１回再ビルドをしないと、正しく反映されなくなったりするので再ビルドする	
## 18:17 画像取得関数fetchImagesを作成
dioがついかされたら、これを使って、画像の取得というのをやっていきます
非同期関数も説明しないといけないですけど
まず、画像の取得の関数を作る　いったんここclass _PixabayPageState extends State<PixabayPage> {の中に
返り値なしでvoid fetch（取得という意味）fetchimagesという関数を作ります
この中でdioを呼び出していきます
```dart
	Dio().get
```
getという関数があります。getの（）にURLを与えるとさっきのJSONのデータを取得することができる仕組みになっています

## 19:25 非同期処理 Future async await についての解説
それではURLを取得していきます
PixabayのExampleを使用して学んでいきます
（）内に文字列なのでシングルコーデで囲うことを忘れずにサンプルのURLを貼り付ける
getの型をみる
Future<Response>という型になっている。このFutureというのが少しやっかい。ちょっと時間のかかる処理
FutureじゃなくResponseで受け取る場合、工夫する必要がある
それがasync/awaitという方法です
もしFutureというのを見たら、async/awaitを使うんだというぐらいの認識で最初は構わない
非同期処理については後ほど。
まずは使い方として、関数の前にawaiteとつけるだけ。なんですが、かんすうのなかで、asyncというキーワードを付ける必要があります。
```dart
	void fetchimages() async {
		Response response = await Dio().get('取得したいURL');
	}
```
voidは返り値なんのですが、asyncをつけるときはFuture<void> fetchimages() async {　と変更する
これでResponseでうけとれるようになる
最初はFuture見たらawait付けるんだぐらいの感覚で今は機械的にやってしまってよいかなと思います
	
## 21:43 initStateで関数を呼び出しJSONデータの取得を確認
	Responseの中で色々受け取取っている中、色々ありますが、その中のdataにさっきのMap型のものが入っています。
	確認してみます。
```dart
	int total = respose.data['total'];
	print(total);
```
この関数自体は作っただけで、どこでも呼ばれていないので、呼び出さないと行けないんですが
呼び出すタイミングは、今回このアプリが実行されて、このStateができたときに１回だけ呼ぶというのをやりたいと思います
それがinitStateというとこでできます
iniまで入れると候補が出るのでinitStateを選択。そうすると下記が自動で記載される
```dart
	@override
	  void initState() {
	    super.initState();
	    //最初に一度だけ呼ばれる
	  }
```
ここの中で書かれた処理が必ず一度だけ呼ばれるよう、最初に１回だけ呼ばれるようになっています。
ここにfetchimagesを呼んであげましょう
```dart
	  void initState() {
	    super.initState();
	    //最初に一度だけ呼ばれる
	    fetchimages();
	  }
```
  これで実行（成功）すると、コンソール上にtotalのvalue値が表示される

## 24:18 List型の状態変数hitsを定義してデータを格納する
配列の取り方は
前回出てきた状態というもので持ちます。状態の持ち方です。
変数を用意する。名前は難しいでうsが、型はListでokです
名前はhitsというkey名だったので、わかりやすくhitsにします。
List hits = []　かっこのなかは初期値を入れる
最初は何も入っていないっていうので、空のリストを入れておくのがいいと思います
```dart
List hits = [];//からの状態
```
中身を取りに行く書き方はhitsのkeyに対して、アクセスればいいので
```dart
hits = respose.data['hits'];
```
データを入れたら、画面を更新したいので、その下にsetState(() {});を忘れないうちに入れておく
```dart
hits = respose.data['hits'];
setState(() {});
```
これで、ここの配列のデータが、変数のhitsという変数に入ってきて、入ったあとに画面が再描画されるというところまでできました

## 26:10 GridView.builderの使い方を解説

今回表示上では格子状で表示させたいので、Gridviewというのを使っていきます。
bodyの中にGridView.builderがあるのでこれを使っていきます
表示場なのでWidgetないのScaffoldの中で展開していきます
gridDelegateっていうのが勝手に入っていますが、そこにカーソルを当ててあげると何の型を与えればいいかがでてきます

このindexを使用して
一個づつ要素を取り出さなければならない
一個なんでhitにしておきましょうか
hitsにたくさんデータが入っているので、これが配列、リストだよとなっている
リストの指定した要素の番号で、一個ずつデータを取りダウには、角かっこのなかで０とか１とか指定すればよかったですよね。
上記のindexには、０～１９番目の値が順番に入ってくるので、それを一個づつ取り出したい場合は、角かっこに書けばいい
これで順番に値を取り出すことができます
あとはこのhitをつかてあげてこの格子状の一個つづ何を出すかっていうのをやってみればいいわｋです
すこしわかりずらいのでindexが何をしているかみていきます
これを見るのはテキストとかを表示してあげればいい
return Text(index.toString());
こうすることで、アプリ、画面上で、格子状に数字が表示されていることが見えます
０１２３４５…が一個一個の要素が、returnされたWidgetになっている作りになっていることがわかります

URLから画像を表示させるためにはImage.networkというのを使います
先ほどのpixabayのpreviewURLに画像データが入っています
これを取って使用するには
```dart
return Image.network(hit['previewURL']);
```
これで画像一覧取得することができました
	
## 32:17 【次回予告】 文字入力機能とシェア機能の追加
今は決め打ちで１９個しか取れていないので
TextFormFieldとかを追加して、自分で検索したワードを入力して、この別の画像を取得したりとか
この画像を見られるだけじゃ面白くないので、これを共有する、
TwitterとかInstagramとかあとGoogleフォトに保存したりとかそういうことができるようにしていきます
次の記事に書いていきます
	
## 32:51 このチャプターのまとめ
>WebAPI を使ったアプリ開発の前編が終了しました。ここまでで学んだことをおさらいしましょう。

>インターネットを通じて利用できる WebAPI を使えば他のサービスをアプリに組み込める
>JSON 形式のデータは key とそれに対応する value の集まりで構成されている
>DartPad を使えばお手軽に dart を実行できる
>JSON 形式のデータを dart では Map<String, dynamic> として扱う
>複数の要素が連なっている場合は [] を使って List として表現できる
>flutter pub add で外部パッケージを追加できる
>Future は await で待つことで値を取得できる
>initState の中で関数を実行すれば初めに一度だけ実行される
>GridView を使えば格子状に要素を並べられる

>次は後半戦です。閲覧しかできないこのアプリをもっと便利にしていきます！