Flutter
https://cdn.arstechnica.net/wp-content/uploads/2018/06/7-2-1.jpg
環境構築
$ flutter doctor
以下 doctor に指摘されて行ったこと
$ brew install cocoapods; pod setup;
時間かかる
Launch Xcode and install additional required components when prompted.
XCode起動してインストール
Android Studio のインストール / Flutter プラグインのインストール
IntelilJ IDEA の Flutter プラグインのインストール
環境構築後、適切にPATHが設定できれば以下のコマンドでFlutterアプリのScaffoldingが可能
$ flutter create app_name
公式サイト: Write Your First Flutter App, part 1 & part2
Flutter ではほぼ全てが Widget という単位
Widget は build() で何を描画するか指定が必須
テーマ、アニメーション、レイアウト、ジェスチャー検出も全て Widget
パディングやマージンも Widget
Scaffold は Widget tree なるものを提供する Meterialライブラリ
Material はマテリアルデザインを提供する
StatefullWidget
2つのクラスが必要
1. StatefulWidget
2. State
StatelesWidget
不変、よってコンパイル時にすべての値が決定してる必要がある
状態(State) → Widgetが構築されたときの情報を保持し、Widgetのライフサイクル中に変化する可能性のあるもの
Flutterで状態を扱うためにはWidget内にStateクラスを持たせる
StateクラスはStatefulWidgetを継承したクラスに関連付けすることが可能
つまり extends State<SomeStatefulWidgetClass> の指定は必須ではない…(?)
code:stateful_widget.dart
// Class定義が循環参照のようになっているが、問題ないらしい...
class RandomWordsState extends State<RandomWords> { // RandomWords Widget 向けの状態クラス
@override
Widget build(BuildContext context) { // Widget を返す build メソッド
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => RandomWordsState();
}
State内の setState は build() を呼び出す
React.js の setState からの render と同じ
setStateの外側でデータを更新して、空のクロージャ関数で setState することも可能だが非推奨
なるべく setState((){}) の中でデータを更新すること
Flutter の画面遷移はスタックで管理
Navigator.of(context).push() でスタックにプッシュ
Udacity Flutterコース
YouTubeの自動生成の日本語字幕でも意味がわかる
8: Android Studio での Flutter インスペクタの使い方
12: Widget をデザインする際の基本的な考え方が動画で示されわかりやすい
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ソーシャルログイン
Firebase との連携
Flutter 公式の Firebaseプラグイン
https://www.youtube.com/watch?v=DqJ_KjFzL9I
Firebaseのデータベース向けのプラグインは使用するDBによって使いわけること
firestore
firebase database
Push通知
Firebase Messaging(?)
複雑なアプリを作るには
Build reactive mobile apps with Flutter (Google I/O '18)
https://www.youtube.com/watch?v=RS36gBEp8OI
アプリのレイアウト
Containerは子Widget(child)をカスタマイズする
パディング、マージン、ボーダー、背景色などを追加したいときに使う
レイアウトの注目点
1. 行と列を確定する
横に並ぶ要素は Row Widget
縦に並ぶ要素は Column Widget
2. レイアウトにグリッド構造は含むか?
3. 重なる要素はあるか?
4. タブが必要なUIか?
5. アライメント、パディング、枠線が必要な領域に注意する
Row, Column, Flex の child で Expanded を使うと、親Widgetの領域を全部使う
複数の Expanded が children にいたら均等割当
コンテナのサイズは、childの大きさに調整される
childがなければ指定された範囲全部を埋める
背景色の指定 → colorプロパティ
Widgetデザイン
親のWidgetデザインは子に継承される
Widgetメモ
AppBar → アプリ画面上部のバー、ユーザーが現在どこのルートにいるのかを示すのに良い
Container → 子のWidgetの背景画像、パディング、余白、その他の一般的なレイアウトを定義するのに便利
Divider → 水平区切りの定義
Widgetでのピクセル指定は論理ピクセル数で、実際のピクセル数とは一致しない
実際のデバイスの画素数に合わせて変わる、以下の概念を参照のこと
iOS なら points
Android なら density-independent pixels
マテリアルデザインのアイコン一覧は以下のページで確認可能
デバイスの画面サイズを基準に幅とかを指定したい!
PortraitViewは縦持ち時
LandscapeView はスマホを横に倒したときの言い方
レスポンシブデザイン
MediaQuery.of
OrientationBuilder widget/方向ビルダー
OS毎に処理を分ける分岐コード
Theme.of(context).platform == TargetPlatform.iOS ? iOSの処理 : Android の処理
ボタンは onPressed が null だと色指定が反映されない
画像素材
AssetsImageクラス
Android Studio / IntelliJ での tips
Widgetクラス名にカーソルをもっていき Alt+Enterで親Widget追加コードを1発で補完できる
Flutter ではデザイン指定やジェスチャ検出なども一律に Widget クラスなので、このコマンドは非常に便利
用語集
Route → アプリケーションのページや画面のことを指す
DEX → Dalvik EXecutable → DalvikおよびARTで実行可能なバイトコードのこと
iOS関連
table:関連するファイル
ファイル名 役割
/ios/Runner/Assets.xcassets アイコン等のアプリリースが保存されるディレクトリ
/ios/Runner/Info.plist 設定ファイル。連携のためFirebaseが生成したplistを保存する
/ios/Runner/Base.lproj/LaunchScreen.storyboard アプリ起動時の画面を制御するための設定ファイル
/ios/Runner.xcworkspace GoogleService-info.plist を保存する場所
firebase との連携で編集が必要なファイルは dart の pubspec.yaml のみ。 iOS specific なファイル編集の必要なし launch の引数に FIRDebugEnabled
XCode10 でビルドが失敗する件の対応
Android関連
table:関連するファイル
ファイル名 役割
/android/app/src/main/AndroidManifest.xml アプリの設定と各コンポーネントの定義ファイル
google-services.json firebase からDLする設定ファイル android/app 以下に保存する
/android/build.gradle google-service への依存設定( classpath 'com.google.gms:googleservices:3.1.0' )を追記する必要があるファイル
/android/app/build.gradle googleプラグインの設定( apply plugin: 'com.google.gms.googleservices' ) を末尾に追記する必要があるファイル
firebaseへのアプリ登録時に Debug signing certificate SHA-1 を設定する方法
$ keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore # for debug
firebase analytics を enable debug mode で動かす $ adb shell setprop debug.firebase.analytics.app <package_name>
ビルド時にエラーが発生する
code:64kerror
D8: Cannot fit requested classes in a single dex file. Try supplying a main-dex list.
# methods: 69615 > 65536
FAILURE: Build failed with an exception.
app/build.gradle に以下を追記
defaultConfig に追記 → multiDexEnabled true
dependencies に追記 → compile 'com.android.support:multidex:1.0.3'
その他
iOSシミュレータが異常に遅いときは Slow animation モードになっていないか確認する
Flutter IDE の tips
一度アプリがクラッシュしたら、 Hot Reload ではなく Hot Restart しないとシミュレータが更新されない
デバッグ方法はまずこちらを読む
To debug your Flutter app using breakpoints:
1. Open the source file in which you want to set a breakpoint.
2. Locate the line where you want to set a breakpoint, click on it, then select Run > Toggle Line Breakpoint in the menu. Alternatively, you can click in the gutter (to the right of the line number) to toggle a breakpoint.
3. If you weren't previously running in debug mode, stop the app.
4. Restart the app using Run > Debug in the menu.
The IntelliJ editor launches the Debugger UI and pauses the execution of your app when it reaches the breakpoint. You can then use the controls in the Debugger UI to identify the cause of the error.
Practice using the debugger by setting breakpoints on the build() methods in your Friendlychat app, then run and debug the app. You can inspect the stack frames to see the history of method calls by your app.
Flutter Plug-in 等を追加したあとに MissingPluginException が出たときはHot Reload ではなく再コンパイルしてみる
参考文献
BLoCアーキテクチャの入門記事
Fluttter でのデザイン関連の記事
Flutterをデスクトップで動かす系
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー