目次
第1章 環境構築とアプリの実行 ── Flutter SDK,Android Studio,Xcode
1.1 なぜFlutterが注目を集めているのか
- マルチプラットフォーム
- 高速な実行速度
- 優れた開発者体験
1.2 Flutterの環境構築
- Flutterのインストール
- プラットフォームごとの環境のインストール
- Androidの開発環境をインストールする
- iOSの開発環境をインストールする
- Tips:Xcodeのバージョンを使い分けるインストールのしかた
- Tips:CocoaPodsがインストールできない場合
- Android Studioの設定 ── Flutterと親和性の高いIDE
1.3 fvmによるFlutterのバージョン管理
- fvmのインストール
- fvmを利用したFlutterのインストール
1.4 プロジェクトの作成
- Android Studioでの作成手順
- テンプレートプロジェクトをのぞいてみよう
- fvmの設定
1.5 Flutterアプリの実行
- iOS Simulatorでの実行
- Android Emulatorでの実行
- Android Emulatorを作成する
- Android Emulatorを起動し,アプリを実行する
1.6 まとめ
第2章 Dartの言語仕様
2.1 変数宣言
- 変数と型推論
- 定数 ── finalとconst
- いろいろな初期値の与え方
- 遅延初期化
2.2 組み込み型
- 数値型
- int ── 整数型
- double ── 浮動小数型
- String ── 文字列型
- bool ── 論理型
- List ── 配列
- Set ── 集合
- Map ── 連想配列
- Record ── タプル
- Objectクラス ── すべてのクラスのスーパークラス
2.3 ジェネリクス
- ジェネリッククラス
- ジェネリック関数
2.4 演算子
- 算術演算子
- 比較演算子
- 三項演算子
- カスケード記法
- コレクションのオペレータ
- Spread演算子
- 制御構文演算子
2.5 制御構文
- 分岐
- if文
- if-case文
- switch文
- 式としてのswitch
- ループ
- for文
- while文
- breakとcontinue
2.6 パターン
- マッチング機能しか持たないパターン
- 論理演算子,比較演算子
- 一致判定
- マッチングと分解宣言の2つの機能を持つパターン
- List
- Map
- Record
- Object
- Tips:for-in文での分解宣言
- パターンを補助する構文
- キャスト
- nullチェック
- nullアサーション
- ワイルドカード
2.7 例外処理
- 例外の型 ── ErrorとException
- 例外の捕捉
- 例外の再スロー
- finally句
- アサーション
- Flutterの例外処理
2.8 コメント
2.9 null安全
- null許容演算子
- null認識演算子
- nullアサーション演算子
- タイププロモーション
- そのほかの便利なnull関連演算子
2.10 ライブラリと可視性
2.11 関数
- 引数
- 省略可能引数
- 名前付き引数
- 関数の省略記法
- 第一級関数と匿名関数
2.12 クラス
- ゲッタとセッタ
- いろいろなコンストラクタ
- constantコンストラクタ
- 名前付きコンストラクタ
- factoryコンストラクタ
- クラス継承
- スーパークラスのコンストラクタ
- 暗黙のインタフェース
- 拡張メソッド
- mixin ── クラスに機能を追加する
- Enum
- Enumの宣言
- Enumの利用
- クラス修飾子
- abstract
- base
- interface
- abstractとinterfaceの組み合わせ
- final
- mixin
- sealed
2.13 非同期処理
- Future型
- エラーハンドリング
- Stream型
- Streamの購読をキャンセル,一時停止する
- Stream型を生成する関数
- Streamの終わり
- エラーハンドリング
- StreamController
- ブロードキャスト
- Streamを変更する
- Zone ── 非同期処理のグループ化
- アイソレート
- Flutterアプリとアイソレート
2.14 まとめ
第3章 フレームワークの中心となるWidgetの実装体験 ── StatelessWidget,StatefulWidget
3.1 DartPadでアプリ開発を体験しよう
3.2 状態を持たないWidget ── StatelessWidget
- 独自のStatelessWidgetを定義する
3.3 状態を持つWidget ── StatefulWidget
- Widgetのタップ操作を検知する
- StatefulWidgetを継承する
- Widgetの状態を変化させる
3.4 まとめ
第4章 アプリの日本語化対応,アセット管理,環境変数
4.1 パッケージやツールを導入する
- パッケージの導入方法
- パッケージバージョンの指定方法
- パッケージバージョンの更新方法
- Tips:セマンティックバージョニングについて
4.2 アプリを日本語に対応させる
- 意図せず英語表示されるケース
- フレームワークが提供する表示文字列
- 日付フォーマット
- アプリを日本にローカライズする
- フレームワークが提供する表示文字列を日本語化する
- 日付フォーマットを日本語化する
- iOSアプリの対応言語を設定する
- メッセージをローカライズする
- コードジェネレータを設定する
- arbファイルを作成する
- ローカライズされたメッセージを表示する
- arbファイルの扱い方
- プレースホルダ
- 単数形と複数形の対応
- 複数の言語への対応
4.3 プロジェクトにアセットを追加する
- アプリに画像を追加する
- 端末の解像度に応じて画像を切り替える
- flutter_gen ── 型安全にアセットを扱うパッケージ
- flutter_genを導入する
- SVG画像の利用
- その他のアセット
4.4 dart-define-from-file ── 環境変数を扱う
- 環境変数をJSON形式で記述する
- 環境変数をコードから参照する
4.5 まとめ
第5章 テーマとルーティング
5.1 テーマ ── アプリ全体のヴィジュアルを管理
- フレームワークによるテーマの自動計算機能
- ダークモード対応
- アプリ独自のテーマ管理
- Theme Extensionを利用したアプリのサンプル
- Tips:Cupertino(クパチーノ)デザイン
5.2 ナビゲーションとルーティング ── 画面遷移を実現する3つの手法
- NavigatorウィジェットとRouteクラスによる画面遷移 ── Navigator 1.0
- 画面間でのデータの受け渡し
- 名前付きルートによる画面遷移 ── Navigator 1.0(非推奨)
- 名前付きルートの制限事項
- Routerウィジェットによる画面遷移 ── Navigator 2.0
- go_routerによる画面スタックの書き換えを体験する
- GoRouteで入れ子構造を作る
- goとpushの違い
5.3 まとめ
第6章 実践ハンズオン(1) ── 画像編集アプリを開発
6.1 開発するアプリの概要
- スタート画面
- 画像選択画面
- 画像編集画面
- 開発の土台づくり
- テーマと画面遷移の方針
6.2 プロジェクトを作成する
- 開発の土台づくり
6.3 アプリ起動後のスタート画面を作成する
- レイアウトを作成する
6.4 テーマをアレンジする
6.5 アプリを日本語化する
- パッケージを導入する
- ローカライズの構成ファイルを作成する
- arbファイルを作成する
- ローカライズされたメッセージを適用する
- App Storeでの表示言語を設定する
6.6 画像選択画面を作成する
- メッセージを追加する
- レイアウトを作成する
- 画像ライブラリから画像を取得する
- パッケージを導入する
- iOSネイティブの設定を行う
- 画像を取得する処理を実装する
- 画像取得処理をWidgetに組み込む
6.7 画像編集画面を作成する
- メッセージを追加する
- レイアウトを作成する
- 画像編集画面への遷移を実装する
- アイコンを追加する ── flutter_genによるアセット管理
- 画像を編集する処理を実装する
6.8 まとめ
- Tips:WidgetとStateのライフサイクルについて
第7章 状態管理とRiverpod
7.1 Flutterアプリにおける状態管理
7.2 Riverpodとはどのようなパッケージか
- Tips:宣言的UIとしてのFlutter
- Riverpodの主要なクラス
- 実装サンプル
7.3 Riverpodの関連パッケージ
- 基本機能を提供するパッケージ
- Providerのコードを生成するパッケージ
- 静的解析を行うパッケージ
- 関連パッケージまとめ
7.4 Riverpodの使い方
- Providerの種類
- 関数ベースのProvider
- クラスベースのProvider
- 非同期処理を行うProvider
- 非同期なProviderとRaw型
- Providerから値を取得する
- Providerの値をフィルタする
- Providerのライフサイクル
- Providerにパラメータを渡す
7.5 まとめ
第8章 実践ハンズオン(2) ── ひらがな変換アプリを開発
8.1 開発するアプリの概要
- 入力状態
- レスポンス待ち状態
- 変換完了状態
- 開発の土台づくり
- テーマと画面遷移の方針
8.2 プロジェクトを作成する
8.3 アプリで使用するパッケージを導入する
- riverpod_lintを設定する
8.4 入力状態のウィジェットを実装する
- レイアウトを作成する
- レイアウトを表示する
- 入力値のバリデーションを行う
8.5 入力文字を取得する
8.6 ひらがな化するWeb APIを呼び出す実装をする
- リクエスト,レスポンスオブジェクトを定義する
- アプリケーションIDを設定する
- Web APIを呼び出す
8.7 アプリの状態を管理する
- 状態を表現するクラスを作成する
8.8 状態に応じて表示を切り替える
- レスポンス待ち状態のウィジェットを実装する
- 変換完了状態のウィジェットを実装する
- 画面の切り替えを行う
- ひらがな変換処理の呼び出しを修正する
8.9 まとめ
第9章 フレームワークによるパフォーマンスの最適化 ── BuildContext,Key
9.1 BuildContextは何者なのか ── Element
- 祖先の情報にアクセスできるBuildContext
- Elementがツリーを構成していく工程
- StatefulWidgetの状態を保持する役割
- Tips:宣言的UIとElementの再利用
9.2 Elementの再利用とパフォーマンス ── RenderObject
- RenderObjectは高コストな計算を行う
- RenderObjectは状態を持つ
- Elementの再利用はパフォーマンスに影響する
9.3 Keyは何に使うのか
- Elementが再利用される条件
- Elementが再利用される様子を見てみよう
- Keyを利用したElementの再利用
- Keyの種類
9.4 局所的にWidgetを更新するしくみ ── InheritedWidget
9.5 まとめ
第10章 高速で保守性の高いアプリを開発するためのコツ
10.1 パフォーマンスと保守性,どちらを優先すべきか
- 高速でないアプリとは
- 高速だが保守性が低い実装
10.2 高速で保守性の高い実装
- buildメソッドで高コストな計算をしない
- buildメソッドで大きなウィジェットツリーを構築しない
- ウィジェットツリーの階層が浅くなるようウィジェットの選択を見なおす
- const修飾子を付与する
- const修飾子が使えるようウィジェットの選択を見なおす
- 独自のウィジェットクラスにconstantコンストラクタを実装する
- 状態を末端のウィジェットに移す
- Riverpodの状態監視は末端のウィジェットで行う
- Tips:アプリのパフォーマンスを計測する
10.3 まとめ
第11章 Flutterアプリ開発に必要なネイティブの知識
11.1 ネイティブAPIのバージョンと最低サポートOSのバージョン
- 最低サポートOSのバージョン
- iOSの最低サポートOSバージョンを設定する
- Tips:XcodeのBuild Settings
- Androidの最低サポートOSバージョンを設定する
- ビルドSDKバージョン
- iOSのビルドSDKバージョンの設定
- AndroidのビルドSDKバージョンの設定
- ターゲットSDKバージョン
11.2 アプリの設定変更
- アプリ名
- iOSのアプリ名を変更する
- Androidのアプリ名を変更する
- アプリアイコン
- iOSのアプリアイコンを変更する
- Androidのアプリアイコンを変更する
- アプリアイコンを手軽に生成するパッケージ
- スプラッシュ画面
- iOSとAndroidで異なるスプラッシュ画面の位置付け
- iOSのスプラッシュ画面
- Androidのスプラッシュ画面
- スプラッシュ画面を手軽に実現するパッケージ
- アプリのID
- iOSのアプリIDを設定する
- AndroidのアプリIDを設定する
11.3 アプリの配布とコード署名
- iOSのコード署名
- 管理の難しい秘密鍵
- アプリに署名する
- Androidのコード署名
- apkファイルとaabファイル
- アプリに署名する
- aabファイルをアップロードする