Flutter学習9日目 -Udacity 1. ウィジェットの紹介（前編）-

※自分の学習記録のメモとしてこの記事を書いています。

1日目：Flutter学習1日目 -公式を読む 1. インストール編-
2日目前編：Flutter学習2日目前編 -公式を読む 2. エディターの設定編-
2日目後編：Flutter学習2日目後編 -公式を読む 3. テストドライブ編-
︙
7日目：Flutter学習7日目 -公式を読む 8. レイアウトのチュートリアル-
8日目：Flutter学習8日目 -公式を読む 9. インタラクティブな機能の実装-
9日目：Flutter学習9日目 -Udacity 1. ウィジェットの紹介（前編）-

今回からは今までと違って公式のドキュメントを読み進めるのではなく、UdacityというサイトのFlutterレッスンを進めていきます！
Lesson1とLesson2があり、今日は[Lesson1](https://classroom.udacity.com/courses/ud905)をやっていきます👩‍💻

# Lesson1: Flutterフレームワーク
Flutter フレームワークの基本を理解し、アプリにウィジェットやステートを組み込み、Flutter のツールを使って開発プロセスを強化しましょう。
この内容は3時間50分かかります。

![スクリーンショット 2020-09-20 16.11.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/1421be29-dd77-1acb-8391-d7c153899351.png)

# 1. イントロダクション（動画）

※Youtubeが限定公開だったため、URLは念の為伏せています。Udacityから御覧ください。

英語なので英語できない方はここで離脱してしまうかもしれないですが、設定＞字幕＞自動翻訳＞日本語である程度はわかるようになるので諦めずに視聴してみてくださいね😌

この動画の概要

- Flutterとは何か
- Flutterの特徴
    - 最新のリアクティブフレームワーク
    - 高速な2Dレンダリングエンジン
    - 迅速な開発のためのツール
    - アプリのUIコンポーネントの旺盛要素であるウィジェット
- このコースの内容
    - 高品質なインタラクティブアプリ
    - アプリの構造化と設計
    - Flutterを使用して、効率的かつ迅速にアプリを構築
    - ウィジェット
    - アプリの状態（データの取得とアニメーション作成）
    - マテリアルデザイン
    - ユーザーインタラクションとジェスチャー
    - パッケージ

# 2. なぜFlutterなのか？（動画）

- Flutterが出来た理由
    - 優れたアプリをすばやく作成するため
- 素早くアプリが作れる仕組みについて
    - プラットフォームとデバイス間で一貫したUIを提供するレンダラー

# 3. なぜDartなのか（動画）

- Dartは強く型付けされたオブジェクト指向言語
- 開発中および本番環境でのパフォーマンス
- アプリの安定したホットリロード
- static型とsound型システム
    - コンパイル時にバグをキャッチし、コードが大きくなるにつれてコードを管理するのに役立つ

# 4. 環境の設定

[https://flutter.io/setup](https://flutter.io/setup)に従って環境の設定。
設定済みなのでこちらはスキップします。

# 5. Flutterアプリを作る（動画）

- いくつかのコードを見てFlutterを学んでいきます
    - モダンなリアクティブフレームワーク
    - 速い2Dのレンダリングエンジン
    - 開発ツール
- Android Studio内であたらしいFlutterプロジェクトを作成

![スクリーンショット 2020-09-25 13.32.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/2a945e08-7ec2-72cf-4719-157798c820aa.png)

- Flutter Applicationを選択

![スクリーンショット 2020-09-25 13.34.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/94486c78-9f35-3b6a-5c2a-4f4bb2283fc5.png)

- Project Nameを変更します
    - ※コマンドラインでも作成することが可能です 

![スクリーンショット 2020-09-25 13.36.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/1d72a6df-485d-dcde-50c1-33dc3e0380f7.png)

- プロジェクトを作成すると様々なファイルが自動的に生成されます
    - 1つのFlutterコードでiOSとAndroidの両方のコードに組み込むことができるため、各プラットフォームのディレクトリがあることに注意してください
    - 威圧的に感じるかもしれませんがlibディレクトリ内のmain.dartを参照するだけで済みます
- main.dartファイルを開きます
    - サンプルのコードが表示されています
    - このサンプルコードに興味がある場合はインラインコメントを読んで下さい

![スクリーンショット 2020-09-25 13.42.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/0a225b94-5c93-e181-54af-0b749139c39b.png)

- これを全て削除します

![スクリーンショット 2020-09-25 13.47.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/4ccb21ca-72e4-0660-b7a9-560bf8259e66.png)

- [このコード](https://github.com/flutter/udacity-course/blob/master/course/01_hello_rectangle/solution_01_hello_rectangle/lib/main.dart)を貼り付けます
- このコードで「Hello」という単語が入った色付きのコンテナが表示されます
- HelloRectangleアプリを実行します
- エミュレーターまたはデバイスを実行します
- ここではエミュレーターを使用します
- エミュレーターでアプリをビルドして実行します
    - エミュレーターを実行するには、エミュレーターを選択するかデバイスをリストするドロップダウンからデバイスを選択します
    - ここに少なくとも1つのデバイスがリストされている必要があります
    - ない場合は正しくセットアップしたか確認してください
- ホーム画面が表示されます

![スクリーンショット 2020-09-25 13.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/6fd8fa21-f1b9-60a2-2d20-a3976f23b64c.png)

- 緑色の再生ボタンを押すことができます
    - 構築された詳細はコンソールに出力されます

![スクリーンショット 2020-09-25 14.02.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/c3b0306d-1ef1-6278-8b11-75e0f57a0ac5.png)

- これで準備が整いました

# 6. 出題： Hello Rectangleアプリを作成する

- 5. の動画の内容が出来たかの確認をします。

# 7. Flutterのりアクティブフレームワークについて（動画）

- Widgetについて
    - ウィジェットはFlutterアプリの基盤
    - UIとほぼ全てがDartで記述されたウィジェット
    - 状態も管理
- レンダリング
    - アプリ側で全てのレンダリングを行う
    - 高速

# 8. Flutterの開発者ツールについて（動画）

- 開発とデバッグのための機能
    - ホットリロード
    - ウィジェットインスペクター
    - コードの自動フォーマッター
- ホットリロード
    - デバイスとエミュレーターの両方で機能
    - 再起動は緑のボタンを押すだけ（Android Studio）
- Flutter Inspector
    - デバイスのピクセル
    - ウィジェットツリー
    - ウィジェットが作成されたコード行
- オートフォーマッター

# 9. ウィジェットの素晴らしいところ（動画）

- テーマと色を簡単に追加
- アプリのレイアウトとユーザー操作を追加
    - テーマ
    - アニメーション
    - レイアウト
    - ジェスチャー
- ステートフルウィジェット

# 10. 出題：フラッターウィジェットを探る

Q1. 次のタスクに当てはまるウィジェットを「MaterialApp」「Opacity」「Padding」「Dropdown」「GridView」「Checkbox」から選びます。
1. アプリの音量調整をしたいです。
2. ユーザーにスクロールしてもらいたい写真が大量にあるので、効率的にスクロールさせたいです。
3. 私はフォームを作成していますが、ユーザーが聴く音楽の種類をリストから選択できるようにしたいです。
4. ユーザーが誕生日の月をリストから選択できるようにしたいです。
5. アプリの画面に重なるような半透明のライトボックスを作りたいです。

Q2. 次のタスクに当てはまるウィジェットを「Padding」「GestureDetector」「Align」「Flex」「MaterialApp」「Center」「Stack」から選びます。
1. この画像を画面の中央に表示させたいです。
2. 私は3つのコンテナを持っていて、それぞれが常に画面の3分の1を占めるようにしたいです。
3. 送信ボタンが常に画面右上にあるようにしてほしいです。
4. アプリの下部に、ページ上の他のウィジェットの「上」に重ねて常に表示される粘着性のあるフッターが欲しいです。
5. 左にスワイプしたときにウィジェットでアクションを実行したいです。

Q1の答えは、
1. Slider
2. GridView
3. Checkbox
4. Dropdown
5. Opacity

Q2の答えは、
1. Center
2. Flex
3. Align
4. Stack
5. GestureDetector
です。

# 11. Hello Rectangleの解剖（動画）
 
- printステートメントでデバッグする
- マテリアルデザインパッケージをimport
- Containerウィジェット
- MaterialAppウィジェット
- ウィジェット関数を自分で作成する

# 12. 独自のウィジェットを構築する（動画）

- デザインから分解して考える
    - まずはContainerから始まる
    - 横に並べるためにRowウィジェットを使用
    - アイコンはIconウィジェット
    - テキストはTextウィジェット
    - 余白をつけるにはPaddingウィジェット
    - テキストを天地中央に配置するにはCenterウィジェット
    - Inkwellウィジェットでタップアニメーションを追加
    - Inkwellウィジェットの親はMaterialウィジェットである必要があるので一番外側に追加
    - Containerウィジェットの直下だとPaddingプロパティが使える

# 13. 出題：独自のウィジェットをコード化

この演習では、カテゴリウィジェットの実装を終了します。

サイズを推測する必要がないように、これらを使用します。
- ウィジェットの高さ: 100.0
- アイコンのサイズ: 60.0
- アイコン-背景色付き幅: 70.0
- テキストサイズ: 24.0

## 目標
既存のFlutterウィジェットを使って、カスタムのCategoryウィジェットを作成します。
お好みに合わせてウィジェットをカスタマイズします。

## ステップ
1. category.dartとmain.dartのTODOを以下の仕様で記入してください。
2. 必要に応じてカテゴリウィジェットをカスタマイズしてください。いくつかのアイデアは以下の通りです。

## 仕様
- アイコン、色、テキストは、インスタンス化時にCategoryウィジェットに渡されます。これらは必須です。
- カテゴリウィジェットの高さは100.0です。パディングは8.0です。
- ウィジェットのボーダー半径はカテゴリの高さの半分(この場合、50.0)です。高さとボーダー半径の両方を定数として定義できます。
- アイコンのサイズは60.0です。アイコンの周りのパディングは16.0です。
- テキストサイズは24.0です。
- `onTap`関数がnullの場合、InkWellはアニメーションしません。今のところ、プレースホルダとして print 文を使用してください。`onTap: () { print('I was tapped!'); }`
- InkWellのスプラッシュとハイライトの色は、私たちが渡した色にする必要があります。

スターターコードとスクリーンショットは[こちら](https://github.com/flutter/udacity-course/tree/master/course/02_category_widget/task_02_category_widget)にあります。
GitHubからプロジェクトをダウンロードする方法がわからない場合は、コースの[README](https://github.com/flutter/udacity-course/)の説明を参照してください。

## 実践

1. `git clone https://github.com/flutter/udacity-course.git` でクローン
2. Android Studioを起動します
3. 「Open an existing Android Studio project」から`udacity-course/course/02_category_widget/task_02_category_widget/`を開きます
4. 緑の再生マークでRUNさせると薄緑色の画面が表示されました![スクリーンショット 2020-09-30 15.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/a6852b00-93c2-ebe6-09cd-8d6f5178782b.png)
5. `return Container()`というコードの中に色々追記していきます
6. IconとTextを横並びにするために`child: Row()`Containerの中に記述
7. `children: [Icon(Icons.cake),Text('Cake')],`をRowの中に記述
8. Containerに高さを固定するため`height: 100.0,`プロパティを追加
9. Paddingを追加するために`child: Padding()`をRowの外に追加
10. Paddingにpaddingを追加するために`padding: EdgeInsets.all(8.0),`プロパティを追加
11. Textを天地中央にするために`Center()`をTextの外に追加
12. Textのフォントサイズは24.0なので`style: TextStyle(fontSize: 24.0)`をTextの中に追加
13. アイコンのサイズは60.0なので`size: 60.0,`をIconの中に追加
14. アイコンの周りのパディングは16.0なのでIconの親に`Padding()`を追加して`padding: EdgeInsets.all(16.0),`プロパティを追加
15. カテゴリウィジェットの高さを定数化するために`final _rowHeight = 100.0;`をimportの下あたりに追記して`height: 100.0,`を`height: _rowHeight,`に変更
16. InkWellを追記したいのでContainerの親に`Material()`を追加し、Containerの子に`child: InkWell()`を追加
17. ウィジェットのボーダー半径はカテゴリの高さの半分(この場合、50.0)なので、`final _borderRadius = BorderRadius.circular(_rowHeight / 2);`を_rowHeight定数の下に記述し、InkWellに`borderRadius: _borderRadius`プロパティを追加
18. `onTap`関数がnullの場合、InkWellはアニメーションしないため、`onTap: () { print('I was tapped!'); }`をInkWellに追加
19. アイコン、色、テキストを名前付き引数で渡す必要があるので、main.dartの`Category()`に`name: _categoryName,color: _categoryColor,iconLocation: _categoryIcon,`を追加
20. `final String name;final ColorSwatch color;final IconData iconLocation;`を追加し、`const Category({})`の中に`@required this.name,@required this.color,@required this.iconLocation,`を追加
21. それぞれcolor, name, iconLocationに替わるところを変更

正解のコードは[こちら](https://github.com/flutter/udacity-course/tree/master/course/02_category_widget/solution_02_category_widget)
![スクリーンショット 2020-09-30 17.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/103543c1-91d2-ab90-75fd-be87643e3519.png)


# 感想
思ったよりボリュームたっぷりだったので、前編と後編に分けます！