「Flutter」の版間の差分
(同じ利用者による、間の80版が非表示) | |||
1行目: | 1行目: | ||
+ | | [[Dart]] | [https://www.typea.info/blog/index.php/category/flutter/ ブログカテゴリ(Flutter)] | [[Android Studio]] | [[Flutter macos]] | [[FlutterFire]] | [[Flutter 手順]] | [[Flutter Riverpod]] | | ||
+ | {{amazon|4798055832}} | ||
==[[Flutter]]== | ==[[Flutter]]== | ||
− | + | {{amazon|B096T3YMZ3}} | |
− | + | <blockquote> | |
− | + | ステップずつ仕組みを学べる良書 | |
− | {{amazon| | + | </blockquote> |
− | |||
− | |||
*https://flutter.dev/ | *https://flutter.dev/ | ||
− | === | + | ===Install=== |
− | *https:// | + | *https://flutter.dev/docs/get-started/install |
− | + | ====[[Windows]]==== | |
− | ==== | + | ---- |
− | *https://flutter.dev/docs/ | + | *https://flutter.dev/docs/get-started/install/windows |
− | + | *インストール | |
− | + | <pre> | |
− | + | > git clone https://github.com/flutter/flutter.git -b stable | |
− | + | </pre> | |
− | * | + | *上記インストールパス\bin にPATHを通す |
− | = | + | ====[[Mac]]==== |
− | ===[[Mac]]=== | + | ---- |
*https://flutter.dev/docs/get-started/install/macos | *https://flutter.dev/docs/get-started/install/macos | ||
− | ====開発者登録==== | + | =====開発者登録===== |
*https://developer.apple.com/ | *https://developer.apple.com/ | ||
− | ====Flutter SDK インストール==== | + | |
+ | =====Flutter SDK インストール===== | ||
+ | ---- | ||
#sdkダウンロード | #sdkダウンロード | ||
#unzipで解凍 | #unzipで解凍 | ||
50行目: | 52行目: | ||
! Doctor found issues in 1 category. | ! Doctor found issues in 1 category. | ||
− | ==== | + | =====[[Xcode]]設定手順===== |
+ | ---- | ||
*xcodeのダウンロード | *xcodeのダウンロード | ||
*command line tools の有効化 | *command line tools の有効化 | ||
− | + | <pre> | |
− | + | $ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/ | |
+ | $ sudo xcodebuild -runFirstLaunch | ||
+ | </pre> | ||
*cocoapods のインストール | *cocoapods のインストール | ||
− | + | <pre> | |
− | + | $ sudo gem install cocoapods | |
+ | $ pod setup | ||
+ | </pre> | ||
*シミュレーターの起動 | *シミュレーターの起動 | ||
− | + | <pre> | |
+ | $ open - a Simulator | ||
+ | </pre> | ||
*プロジェクトの作成 | *プロジェクトの作成 | ||
− | **flutter | + | <pre> |
− | * | + | $ flutter create my_app |
− | **flutter run | + | </pre> |
+ | *プロジェクトディレクトリで以下で実行 | ||
+ | <pre> | ||
+ | $ flutter run | ||
+ | </pre> | ||
+ | |||
+ | ====[[Linux]]==== | ||
+ | ---- | ||
+ | *https://flutter.dev/docs/get-started/install/linux | ||
+ | |||
+ | ===環境=== | ||
+ | ---- | ||
+ | *https://www.typea.info/blog/index.php/2019/10/03/xamarin_flutter/ | ||
+ | ====SDK==== | ||
+ | *https://api.flutter.dev/index.html | ||
+ | ---- | ||
+ | ====Widget==== | ||
+ | *https://flutter.dev/docs/development/ui/widgets | ||
+ | ====拡張パッケージ==== | ||
+ | ---- | ||
+ | *https://pub.dev/flutter/packages | ||
+ | |||
+ | ====[[Flutter]] Studio==== | ||
+ | ---- | ||
+ | UIをデザイナで作成できる | ||
+ | *https://flutterstudio.app/ | ||
+ | |||
+ | ====Sample==== | ||
+ | ---- | ||
+ | https://flutter.github.io/samples/gallery.html | ||
+ | |||
+ | A few resources to get you started if this is your first Flutter project: | ||
+ | |||
+ | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) | ||
+ | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) | ||
+ | |||
+ | For help getting started with Flutter, view our | ||
+ | [online documentation](https://flutter.dev/docs), which offers tutorials, | ||
+ | samples, guidance on mobile development, and a full API reference. | ||
+ | |||
+ | ==プロジェクト== | ||
+ | ===作成=== | ||
+ | ---- | ||
+ | <pre> | ||
+ | $ flutter create --overwrite --org "{パッケージ}" --project-name {プロジェクト名} --platforms=windows,macos,android,ios,web . | ||
+ | </pre> | ||
+ | ===デバイスの確認=== | ||
+ | ---- | ||
+ | <pre> | ||
+ | $ flutter devices | ||
+ | 2 connected devices: | ||
+ | |||
+ | macOS (desktop) • macos • darwin-x64 • macOS 11.6 20G165 darwin-x64 | ||
+ | Chrome (web) • chrome • web-javascript • Microsoft Edge 94.0.992.50 | ||
+ | </pre> | ||
+ | |||
+ | ===実行=== | ||
+ | ---- | ||
+ | *web | ||
+ | <pre> | ||
+ | $ flutter run -d web-server | ||
+ | </pre> | ||
− | ====プロジェクトに[[Firebase]]を統合=== | + | ==[[Firebase]]== |
+ | |||
+ | ===プロジェクトに[[Firebase]]を統合=== | ||
+ | ---- | ||
*プロジェクトフォルダで以下を実行しXcodeで | *プロジェクトフォルダで以下を実行しXcodeで | ||
− | **open | + | *ios |
+ | <pre> | ||
+ | $ open ios/Runner.xcworkspace | ||
+ | </pre> | ||
+ | *macos | ||
+ | <pre> | ||
+ | $ open macos/Runner.xcworkspace | ||
+ | </pre> | ||
+ | *開発者IDを登録 | ||
+ | [[File:0512_ios_bundle_id2.png|600px]] | ||
− | + | [[File:Flutter_xcode_sign.png|600px]] | |
− | |||
− | [[File:Flutter_xcode_sign.png]] | ||
*[[Firebase]] にバンドルIDを登録 | *[[Firebase]] にバンドルIDを登録 | ||
**cd ios | **cd ios | ||
**pod init | **pod init | ||
*https://developers.google.com/identity/sign-in/ios/start-integrating | *https://developers.google.com/identity/sign-in/ios/start-integrating | ||
− | [[File:Flutter_pod_google_signin.png]] | + | [[File:Flutter_pod_google_signin.png|600px]] |
*iPhoneでデベロッパーを信頼 | *iPhoneでデベロッパーを信頼 | ||
**「設定」>「一般」>「プロファイル」または「プロファイルとデバイス管理」の順にタップします。 「エンタープライズ App」見出しの下に、該当する開発元のプロファイルが表示されます。 「エンタープライズ App」見出しの下で開発元のプロファイルの名前をタップし、その開発元を信頼するように設定 | **「設定」>「一般」>「プロファイル」または「プロファイルとデバイス管理」の順にタップします。 「エンタープライズ App」見出しの下に、該当する開発元のプロファイルが表示されます。 「エンタープライズ App」見出しの下で開発元のプロファイルの名前をタップし、その開発元を信頼するように設定 | ||
82行目: | 162行目: | ||
*FirebaseをiOSに追加する | *FirebaseをiOSに追加する | ||
**https://firebase.google.com/docs/ios/setup?hl=ja | **https://firebase.google.com/docs/ios/setup?hl=ja | ||
− | [[File:ios_firebase.png]] | + | [[File:ios_firebase.png|600px]] |
− | [[File:firebase_sdk.png]] | + | |
− | [[File:google_service_info_plist.png]] | + | [[File:firebase_sdk.png|600px]] |
+ | |||
+ | [[File:google_service_info_plist.png|600px]] | ||
+ | |||
+ | *ビルドエラー | ||
+ | |||
+ | diff: /../Podfile.lock: No such file or directory | ||
+ | diff: Manifest.lock: No such file or directory error: | ||
+ | The sandbox is not in sync with the Podfile.lock. Run ‘pod install’ or update your CocoaPods installation.` | ||
+ | **以下xcodeではなく、コマンドで成功 | ||
+ | pos update | ||
+ | pod install | ||
+ | flutter build ios | ||
+ | flutter run | ||
+ | |||
Integrating client project | Integrating client project | ||
Pod installation complete! There is 1 dependency from the Podfile and 4 total pods installed. | Pod installation complete! There is 1 dependency from the Podfile and 4 total pods installed. | ||
93行目: | 187行目: | ||
delhi:ios hirotoyagi$ | delhi:ios hirotoyagi$ | ||
− | == | + | ===[[FlutterFire]]=== |
− | *https:// | + | ---- |
− | + | *[[FlutterFire]] | |
− | + | *https://firebase.flutter.dev/ | |
+ | *https://firebaseopensource.com/projects/firebaseextended/flutterfire/ | ||
+ | *https://github.com/FirebaseExtended/flutterfire | ||
===Flutter.dev 公式プラグイン=== | ===Flutter.dev 公式プラグイン=== | ||
+ | ---- | ||
*https://pub.dev/publishers/flutter.dev/packages | *https://pub.dev/publishers/flutter.dev/packages | ||
− | |||
− | |||
− | |||
− | |||
− | |||
===[[Firebase]] Auth=== | ===[[Firebase]] Auth=== | ||
111行目: | 203行目: | ||
*https://github.com/[[Firebase]]Extended/flutterfire/tree/master/packages/firebase_auth/example | *https://github.com/[[Firebase]]Extended/flutterfire/tree/master/packages/firebase_auth/example | ||
− | ===[[Google]] Sign in=== | + | ====[[Google]] Sign in==== |
*https://pub.dev/packages/google_sign_in | *https://pub.dev/packages/google_sign_in | ||
+ | *[https://www.typea.info/blog/index.php/2020/05/03/flutter-google-sign-in-android-ios/ Googleサインイン試す] | ||
=====example===== | =====example===== | ||
*https://github.com/flutter/plugins/blob/master/packages/google_sign_in/example/lib/main.dart | *https://github.com/flutter/plugins/blob/master/packages/google_sign_in/example/lib/main.dart | ||
+ | |||
+ | ===Firebase Storage=== | ||
+ | ---- | ||
+ | ====CROS [https://firebase.google.com/docs/storage/web/download-files?hl=ja Webでファイルのダウンロード]==== | ||
+ | ---- | ||
+ | 以下のようなエラーが出る | ||
+ | <pre> | ||
+ | Access to XMLHttpRequest at 'https://firebasestorage.googleapis.com/v0/b/rXXXXXX.jpeg? from origin 'http://localhost:58193' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. | ||
+ | </pre> | ||
+ | |||
+ | *cros.json | ||
+ | <pre> | ||
+ | [ | ||
+ | { | ||
+ | "origin": ["*"], | ||
+ | "method": ["GET"], | ||
+ | "maxAgeSeconds": 3600 | ||
+ | } | ||
+ | ] | ||
+ | </pre> | ||
+ | *deploy | ||
+ | <pre> | ||
+ | gsutil cors set cors.json gs://<your-cloud-storage-bucket> | ||
+ | </pre> | ||
+ | |||
+ | ==画面遷移== | ||
+ | *https://qiita.com/granoeste/items/19c119ffc36a016e6223 | ||
+ | *Flutter の画面遷移では Navigator を使用します。 | ||
+ | *Navigator は、ウィジェットをスタックで管理します | ||
+ | *スプラッシュやログイン画面の様な一方通行の画面遷移の場合は、pushReplacement を使用、 この場合、ログイン後はホーム画面がスタックのルートの画面になります。 | ||
+ | *ホーム画面からその他画面、またその他画面への遷移し戻ることが出来るようにする場合は、次の画面への遷移に push、画面を戻るときは pop を使用 | ||
+ | *スタックされたその他画面から、すべての画面をクリアしてホーム画面へ戻りたい場合は、popUntil を使用します。 popUntil は条件に一致するまでスタックから画面をpopして行きます | ||
+ | *ダイアログを表示する場合は、showDialogを使用します。showDialog の内部コードでは、push が呼ばれています。ダイアログを閉じる場合は、pop を使用 | ||
+ | *ログアウトで、全ての画面を破棄してスプラッシュを表示する場合は、 pushAndRemoveUntil を使用します。pushAndRemoveUntil は条件に一致するまでスタックから画面を除いて行きます | ||
+ | |||
+ | ==JSON シリアライズ/デシリアライズ== | ||
+ | *[https://qiita.com/kitoko552/items/81168294f5738175ff1d JSON Serialization] | ||
+ | *[https://qiita.com/kurun_pan/items/455a1e7d6bbd91f0f1f3 JSONファイルの扱い] | ||
+ | json_annotation: ^4.1.0 | ||
+ | json_serializable: ^5.0.0 | ||
+ | build_runner: ^2.1.1 | ||
+ | |||
+ | ==状態管理== | ||
+ | ===[[Flutter Riverpod]]=== | ||
+ | ---- | ||
+ | *[[Flutter Riverpod]] | ||
==Widget== | ==Widget== | ||
123行目: | 262行目: | ||
*https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html | *https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html | ||
*[https://www.youtube.com/watch?v=IYDVcriKjsw Movie] | *[https://www.youtube.com/watch?v=IYDVcriKjsw Movie] | ||
+ | |||
+ | ===const=== | ||
+ | ---- | ||
+ | *https://medium.com/flutter-jp/immutable-d23bae5c29f8 | ||
+ | <blockquote> | ||
+ | Flutterで const SizedBox() など使うことがよくあると思いますが、アプリ各所で何度こう書いても実際に生成されるインスタンスは1つで、それが使い回されます。また、 const Widgetの build() 結果も基本的に同じになるため、それを利用してリビルドの最小化がなされるようにFlutterフレームワーク側で実装されています。 | ||
+ | </blockquote> | ||
==[[Tips]]== | ==[[Tips]]== | ||
*[[Flutter コードサンプル]] | *[[Flutter コードサンプル]] | ||
+ | ===イメージ読み込みエラー対応=== | ||
+ | <pre> | ||
+ | Image.network( | ||
+ | imageURL ?? '', | ||
+ | errorBuilder: (context, object, stacktrace) { | ||
+ | return Text('NO IMAGE'); | ||
+ | }, | ||
+ | ), | ||
+ | </pre> | ||
+ | ===画面サイズoverflow時の対応=== | ||
+ | ---- | ||
+ | [https://www.typea.info/blog/index.php/2019/10/21/flutter_1/ Flutter : 画像の選択] | ||
+ | *サイズがはみ出て、以下のようなエラーが出る場合の対応 | ||
+ | <pre> | ||
+ | ════════ Exception caught by rendering library ═════════════════════════════════════════════════════ | ||
+ | The following assertion was thrown during layout: | ||
+ | A RenderFlex overflowed by 236 pixels on the bottom. | ||
+ | </pre> | ||
+ | *スクロールできるようにする必要があるようなので、以下のサンプルソースに合わせて、スクロールビューの中に入れる。 | ||
+ | *https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html | ||
+ | |||
+ | |||
+ | ===Webで動作しているか判定=== | ||
+ | ---- | ||
+ | *https://stackoverflow.com/questions/57937280/how-can-i-detect-if-my-flutter-app-is-running-in-the-web | ||
+ | <pre> | ||
+ | import 'package:flutter/foundation.dart' show kIsWeb; | ||
+ | |||
+ | if (kIsWeb) { | ||
+ | // running on the web! | ||
+ | } else { | ||
+ | // NOT running on the web! You can check for additional platforms here. | ||
+ | } | ||
+ | </pre> | ||
+ | ===[[Visual Studio Code]]デバッグ=== | ||
+ | ---- | ||
+ | *https://flutter.dev/docs/development/tools/vs-code | ||
+ | |||
+ | ===Microsoft Edgeでデバッグ=== | ||
+ | ---- | ||
+ | *[https://www.typea.info/blog/index.php/2021/08/04/mac_edge_flutter_debug/ MacのEdgeでFlutterのデバッグをする] | ||
===[[Android]]X対応=== | ===[[Android]]X対応=== | ||
*[http://typea.info/blg/glob/2019/10/flutter-androidx.html AndriodX対応] | *[http://typea.info/blg/glob/2019/10/flutter-androidx.html AndriodX対応] | ||
+ | |||
===メニュー=== | ===メニュー=== | ||
====ドロワーメニュー==== | ====ドロワーメニュー==== | ||
*https://flutter.dev/docs/cookbook/design/drawer | *https://flutter.dev/docs/cookbook/design/drawer | ||
− | [https://www.typea.info/blog/index.php/2020/05/ | + | *[https://www.typea.info/blog/index.php/2020/05/04/flutter-drawer-menu/ ドロワーメニューサンプル] |
return Scaffold( | return Scaffold( | ||
appBar: AppBar(), | appBar: AppBar(), | ||
138行目: | 326行目: | ||
body: Center(), | body: Center(), | ||
); | ); | ||
+ | |||
+ | ====ポップアップメニュー==== | ||
+ | *[https://www.typea.info/blog/index.php/2020/05/03/flutter-popupmenu_android_iphone/ ポップアップメニューサンプル] | ||
===画面遷移=== | ===画面遷移=== | ||
179行目: | 370行目: | ||
*https://flutter.ctrnost.com/logic/[[sqlite]]/ | *https://flutter.ctrnost.com/logic/[[sqlite]]/ | ||
*[http://typea.info/blg/glob/2019/12/flutter-sqlite.html sqfliteパッケージの利用] | *[http://typea.info/blg/glob/2019/12/flutter-sqlite.html sqfliteパッケージの利用] | ||
+ | |||
+ | ===トラブル=== | ||
+ | ---- | ||
+ | ====Googleサインインを利用したときに、PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null)エラー==== | ||
+ | ---- | ||
+ | *[https://developers.google.com/android/guides/client-auth フィンガープリントの作成] | ||
+ | *デフォルトパスワードは <code>android</code> | ||
+ | <pre> | ||
+ | keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore | ||
+ | </pre> | ||
+ | *https://www.typea.info/blog/index.php/2020/05/03/flutter-google-sign-in-android-ios/ | ||
+ | *フィンガープリント確認 | ||
+ | <pre> | ||
+ | $ keytool -keystore .android/debug.keystore -list -v | ||
+ | </pre> | ||
+ | *https://developer.android.com/studio/publish/app-signing#sign_release | ||
+ | |||
+ | =====一度誤ったキーストアを使用してしまった場合、flutter clean を行う===== | ||
+ | *https://stackoverflow.com/questions/54557479/flutter-and-google-sign-in-plugin-platformexceptionsign-in-failed-com-google | ||
+ | <pre> | ||
+ | $ flutter clean | ||
+ | </pre> | ||
+ | *keystore共有 | ||
+ | **http://kyokushin.hatenablog.com/entry/2015/01/27/165529 | ||
+ | ====flutter doctor --android-licenses でエラー==== | ||
+ | ---- | ||
+ | <pre> | ||
+ | calcutta:tenarai_online hirotoyagi$ flutter doctor --android-licenses | ||
+ | Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema | ||
+ | at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156) | ||
+ | at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75) | ||
+ | at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81) | ||
+ | at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73) | ||
+ | at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48) | ||
+ | Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema | ||
+ | at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) | ||
+ | at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) | ||
+ | at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) | ||
+ | ... 5 more | ||
+ | </pre> | ||
+ | |||
+ | [[File:flutter_doctor_androidsdk.png|400px]] | ||
+ | |||
+ | ====flutter run (ios) でエラー==== | ||
+ | ---- | ||
+ | <pre> | ||
+ | error: Unable to load contents of file list: '/Target Support Files/Pods-Runner/Pods-Runner-frameworks-Debug-input-files.xcfilelist' (in target 'Runner' | ||
+ | from project 'Runner') | ||
+ | error: Unable to load contents of file list: '/Target Support Files/Pods-Runner/Pods-Runner-frameworks-Debug-output-files.xcfilelist' (in target 'Runner' | ||
+ | from project 'Runner') | ||
+ | </pre> | ||
+ | * Cocoapods の更新 | ||
+ | <pre> | ||
+ | $ sudo gem install cocoapods | ||
+ | $ cd ios | ||
+ | $ pod install | ||
+ | </pre> |
2021年11月1日 (月) 12:05時点における最新版
| Dart | ブログカテゴリ(Flutter) | Android Studio | Flutter macos | FlutterFire | Flutter 手順 | Flutter Riverpod |
目次
Flutter
ステップずつ仕組みを学べる良書
Install
Windows
> git clone https://github.com/flutter/flutter.git -b stable
- 上記インストールパス\bin にPATHを通す
Mac
開発者登録
Flutter SDK インストール
- sdkダウンロード
- unzipで解凍
- ユーザーホームディレクトリ/opt/flutter
- .bash_profile にPATH登録
- export PATH="~/opt/flutter/bin:$PATH"
- flutter doctor コマンドで必要な作業のチェックとヘルプ
$ flutter --version Flutter 1.12.13+hotfix.8 • channel stable • https://github.com/flutter/flutter.git Framework • revision 0b8abb4724 (9 weeks ago) • 2020-02-11 11:44:36 -0800 Engine • revision e1e6ced81d Tools • Dart 2.7.0 delhi:~ hirotoyagi$ flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, v1.12.13+hotfix.8, on Mac OS X 10.15.3 19D76, locale ja-JP) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.4) [✓] Android Studio (version 3.6) [✓] VS Code (version 1.43.2) [!] Connected device ! No devices available ! Doctor found issues in 1 category.
Xcode設定手順
- xcodeのダウンロード
- command line tools の有効化
$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/ $ sudo xcodebuild -runFirstLaunch
- cocoapods のインストール
$ sudo gem install cocoapods $ pod setup
- シミュレーターの起動
$ open - a Simulator
- プロジェクトの作成
$ flutter create my_app
- プロジェクトディレクトリで以下で実行
$ flutter run
Linux
環境
SDK
Widget
拡張パッケージ
Flutter Studio
UIをデザイナで作成できる
Sample
https://flutter.github.io/samples/gallery.html
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our [online documentation](https://flutter.dev/docs), which offers tutorials, samples, guidance on mobile development, and a full API reference.
プロジェクト
作成
$ flutter create --overwrite --org "{パッケージ}" --project-name {プロジェクト名} --platforms=windows,macos,android,ios,web .
デバイスの確認
$ flutter devices 2 connected devices: macOS (desktop) • macos • darwin-x64 • macOS 11.6 20G165 darwin-x64 Chrome (web) • chrome • web-javascript • Microsoft Edge 94.0.992.50
実行
- web
$ flutter run -d web-server
Firebase
プロジェクトにFirebaseを統合
- プロジェクトフォルダで以下を実行しXcodeで
- ios
$ open ios/Runner.xcworkspace
- macos
$ open macos/Runner.xcworkspace
- 開発者IDを登録
- Firebase にバンドルIDを登録
- cd ios
- pod init
- https://developers.google.com/identity/sign-in/ios/start-integrating
- iPhoneでデベロッパーを信頼
- 「設定」>「一般」>「プロファイル」または「プロファイルとデバイス管理」の順にタップします。 「エンタープライズ App」見出しの下に、該当する開発元のプロファイルが表示されます。 「エンタープライズ App」見出しの下で開発元のプロファイルの名前をタップし、その開発元を信頼するように設定
- FirebaseをiOSに追加する
- ビルドエラー
diff: /../Podfile.lock: No such file or directory diff: Manifest.lock: No such file or directory error: The sandbox is not in sync with the Podfile.lock. Run ‘pod install’ or update your CocoaPods installation.`
- 以下xcodeではなく、コマンドで成功
pos update pod install flutter build ios flutter run
Integrating client project Pod installation complete! There is 1 dependency from the Podfile and 4 total pods installed.
[!] Automatically assigning platform `iOS` with version `8.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
[!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `Runner` to `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig` or include the `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig` in your build configuration (`Flutter/Release.xcconfig`). delhi:ios hirotoyagi$
FlutterFire
- FlutterFire
- https://firebase.flutter.dev/
- https://firebaseopensource.com/projects/firebaseextended/flutterfire/
- https://github.com/FirebaseExtended/flutterfire
Flutter.dev 公式プラグイン
Firebase Auth
example
- https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_auth/example
Google Sign in
example
Firebase Storage
CROS Webでファイルのダウンロード
以下のようなエラーが出る
Access to XMLHttpRequest at 'https://firebasestorage.googleapis.com/v0/b/rXXXXXX.jpeg? from origin 'http://localhost:58193' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
- cros.json
[ { "origin": ["*"], "method": ["GET"], "maxAgeSeconds": 3600 } ]
- deploy
gsutil cors set cors.json gs://<your-cloud-storage-bucket>
画面遷移
- https://qiita.com/granoeste/items/19c119ffc36a016e6223
- Flutter の画面遷移では Navigator を使用します。
- Navigator は、ウィジェットをスタックで管理します
- スプラッシュやログイン画面の様な一方通行の画面遷移の場合は、pushReplacement を使用、 この場合、ログイン後はホーム画面がスタックのルートの画面になります。
- ホーム画面からその他画面、またその他画面への遷移し戻ることが出来るようにする場合は、次の画面への遷移に push、画面を戻るときは pop を使用
- スタックされたその他画面から、すべての画面をクリアしてホーム画面へ戻りたい場合は、popUntil を使用します。 popUntil は条件に一致するまでスタックから画面をpopして行きます
- ダイアログを表示する場合は、showDialogを使用します。showDialog の内部コードでは、push が呼ばれています。ダイアログを閉じる場合は、pop を使用
- ログアウトで、全ての画面を破棄してスプラッシュを表示する場合は、 pushAndRemoveUntil を使用します。pushAndRemoveUntil は条件に一致するまでスタックから画面を除いて行きます
JSON シリアライズ/デシリアライズ
json_annotation: ^4.1.0 json_serializable: ^5.0.0 build_runner: ^2.1.1
状態管理
Flutter Riverpod
Widget
Layout
LayoutBuilder
const
Flutterで const SizedBox() など使うことがよくあると思いますが、アプリ各所で何度こう書いても実際に生成されるインスタンスは1つで、それが使い回されます。また、 const Widgetの build() 結果も基本的に同じになるため、それを利用してリビルドの最小化がなされるようにFlutterフレームワーク側で実装されています。
Tips
イメージ読み込みエラー対応
Image.network( imageURL ?? '', errorBuilder: (context, object, stacktrace) { return Text('NO IMAGE'); }, ),
画面サイズoverflow時の対応
- サイズがはみ出て、以下のようなエラーが出る場合の対応
════════ Exception caught by rendering library ═════════════════════════════════════════════════════ The following assertion was thrown during layout: A RenderFlex overflowed by 236 pixels on the bottom.
- スクロールできるようにする必要があるようなので、以下のサンプルソースに合わせて、スクロールビューの中に入れる。
- https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html
Webで動作しているか判定
import 'package:flutter/foundation.dart' show kIsWeb; if (kIsWeb) { // running on the web! } else { // NOT running on the web! You can check for additional platforms here. }
Visual Studio Codeデバッグ
Microsoft Edgeでデバッグ
AndroidX対応
メニュー
ドロワーメニュー
return Scaffold( appBar: AppBar(), drawer: Drawer(), body: Center(), );
ポップアップメニュー
画面遷移
呼び出し元
RaisedButton( onPressed: (){ Navigator.push( context, MaterialPageRoute(builder: (context) => SecondRoute()), ); }, child: const Text('Open Second Screen'),
呼び出し先
import 'package:flutter/material.dart'; class SecondRoute extends StatefulWidget { @override State<StatefulWidget> createState() { return _SecondRouted(); } } class _SecondRouted extends State<SecondRoute> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Center(), ); } }
Dialog
画像選択
画像切り抜き
DB
Sqlite
トラブル
Googleサインインを利用したときに、PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null)エラー
- フィンガープリントの作成
- デフォルトパスワードは
android
keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore
$ keytool -keystore .android/debug.keystore -list -v
一度誤ったキーストアを使用してしまった場合、flutter clean を行う
$ flutter clean
flutter doctor --android-licenses でエラー
calcutta:tenarai_online hirotoyagi$ flutter doctor --android-licenses Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156) at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75) at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81) at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73) at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48) Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ... 5 more
flutter run (ios) でエラー
error: Unable to load contents of file list: '/Target Support Files/Pods-Runner/Pods-Runner-frameworks-Debug-input-files.xcfilelist' (in target 'Runner' from project 'Runner') error: Unable to load contents of file list: '/Target Support Files/Pods-Runner/Pods-Runner-frameworks-Debug-output-files.xcfilelist' (in target 'Runner' from project 'Runner')
- Cocoapods の更新
$ sudo gem install cocoapods $ cd ios $ pod install
© 2006 矢木浩人