Android
iOS
Dart
Flutter

[覚書]Flutter でよくある問題とその解決方法

仕事でFlutterやっていてどハマりしその後解決した時の事と、Webで同様な質問をちらほら見かけたので備忘録的なもの。

Firebase導入で、こんなエラーがでる。

スクリーンショット 2018-08-10 9.51.23.png
問題としてはサポートバージョン違うぞコラァというエラー。
解決方法:firebaseの設定画面でAndroidならこう指定しろというバージョンが表示されるが、Flutterだとこれが出てしまう。出ないバージョンを根気よく探せばエラーがでないバージョンがある。
projectのbuild.gradleのdependenciesで
classpath 'com.google.gms:google-services:4.0.0'
をセットしろと出るのだが、そのままセットするとこのエラーになった。
classpath 'com.google.gms:google-services:3.2.0'
にしたら通った

subprojects {
    project.evaluationDependsOn(':app')
    subprojects {
        project.configurations.all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.android.support'
                        && !details.requested.name.contains('multidex')) {
                    details.useVersion "26.1.0"
                }
            }
        }
    }
}

これも追加したほうが良いみたい。(あまりわかっていないが)

setStateでうまくUIが動かない場合

解決方法というか対処法:StatefulWidgetを使って単体Widgetを入れてState管理してやる
Stateの変更の影響範囲はなるべく小さくする事を心がける。
StatfulWidgetの値のやり取りがメンドイのだが、こういうデザインと思うしか無い。
グローバル変数は敬遠されているのはわかっているが入れ子の入れ子を頻繁に行うFlutterだと、グローバル変数もやむなしなシーンもある気がする。

State変更のせいか沢山APIを叩いてしまう

解決方法: FutureBuilder等を使って組むと良いとStackOverflow等で見かけるが、こいつにAPIを読み込む非同期関数を組み込むと、UIを表示する毎、Stateが変更される毎にAPIを叩いてしまうので、UI読み込みと切り離してAPIを読み込みたい場合はInheritedWidgetを継承したStateクラスを作って、間に噛ませる。APIがロードし終わると、State変更をかける仕組みになるので、Widgetが入れ子になりすぎて、Classが別ファイルになっても、これでState管理する事もできる。
これ以外にBLoCパターンを採用すればできるらしいが、redux系のパッケージを入れなければならないのと、やってみたけど、腑に落ちない感じだったので、私はもう少し成熟するのを待つことにした。

需要があれば、githubにサンプルをアップします。

利用シーン
店舗詳細画面に 詳細API,メニューAPI、スケジュールAPI等、店舗詳細を開いた時に1度読み込んで、それ以降はロードしたくない場合とかに使う。予めPlaceHolder用のUIと、データが伴ったUIの両方を用意しておいて、InheritedWidgetのイベントで置き換える様にする。
APIに限らずSqlite等のi/oアクセスの無駄打ち抑制にも使う。
面倒くささがあるとすれば、ListやMap等に適用できず、いちいちモデルクラスを定義する必要がある点だろうか。

パッケージ系

push通知使いたい

→ FireBaseを使おう。
firebase_core,
firebase_messaging
アプリ起動中じゃないと使えないのでいいなら
→ flutter_local_notifications を使うと良いかも

gps情報を取得したい

location 使おう
location

他のアプリを起動したい

電話番号を電話アプリにパスしたい
google Mapアプリにパスしたい
Webページを表示したい(ユーザーのブラザーアプリで)
→ url_launcherを使おう
url_launcher

Sqliteを使いたい

→ sqfliteを使おう
sqflite
よくFirebaseを勧められるが、有料だから、集計目的以外で使わない方が良いと思うのでsqliteを使いたい需要の為。

後日加筆するかも。