逆引きFlutter

Flutterの学習がてら、[bookmark-with-image](https://github.com/unhurried/bookmark-with-image)（Electron + Vue.js）のFlutterへの移植に挑戦した。（ひとまずは一部分の機能のみであるが、移植版は[bookmark_with_image_flutter](https://github.com/unhurried/bookmark_with_image_flutter)に置いている。）この過程で学習した事項を以下に整理した。

#### Dartの基本を学ぶ

* [Language tour](https://dart.dev/guides/language/language-tour)
* [Library tour](https://dart.dev/guides/libraries/library-tour)
* [Effective Dart](https://dart.dev/guides/language/effective-dart)：コーディングスタイルやドキュメンテーションなど

#### 開発環境を構築する (Windows)

* zipファイルをダウンロードしてPATHを通せばOK。
	* 参考：[Flutter Docs - Windows install](https://flutter.dev/docs/get-started/install/windows)
	* [chocolateyのパッケージ](https://community.chocolatey.org/packages/flutter)は残念ながらあまりメンテされていない。
* エディタはプラグラインが提供されているAndroid Studio, IntelliJ, VS Code, Emacsのいずれかを推奨とのこと。
	* 参考：[Flutter Docs - Set up an editor](https://flutter.dev/docs/get-started/editor)

#### Windowsアプリ（Beta）をビルドする

* Windowsアプリは[Beta](https://flutter.dev/desktop)としてサポートされている。
* 以下の手順でWindowsアプリのビルドを有効化できる。
	* Flutterの設定でWIndowsを有効化する：`flutter config --enable-windows-desktop`
	* [Visual Studio Community 2019をインストールする](https://visualstudio.microsoft.com/downloads/)
	* 新規プロジェクト作成時にWindowsを有効化するオプションを指定する：`flutter create --platforms=windows`
	* [既存のプロジェクトにDesktopを有効化する](https://flutter.dev/desktop#add-desktop-support-to-an-existing-flutter-app)こともできる。
* ビルドしたアプリはMSIXインストーラーに固めることもができるが、手軽にzipファイルにで配布する方法も取れる。
	* 参考：[Building your own zip file for Windows](https://flutter.dev/desktop#building-your-own-zip-file-for-windows)

#### 画面（ページ）切り替えを実装する

* 以下のいずれかの方法で実現できる。
	* [Navigate to a new screen and back](https://flutter.dev/docs/cookbook/navigation/navigation-basics)
		* Navigator.push()/Navigator.pop()で遷移・戻るを実装する。
	* [Navigate with named routes](https://flutter.dev/docs/cookbook/navigation/named-routes)
		* MaterialAppのコンストラクタにてルーティング設定（initialRouteとroutes）を定義して、Navigator.pushNamed()でルートの名前指定で遷移する。

#### Widgetを跨いだ状態管理

* [provider](https://pub.dev/packages/provider)パッケージ (ChangeNotifier) を使う方法を[第一候補とすべき](https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple)とのこと。
	* [List of state management approaches](https://flutter.dev/docs/development/data-and-backend/state-mgmt/options)
	* [Flutterの状態管理いろいろ比較](https://qiita.com/agajo/items/50d5d7497d28730de1d3)

#### トーストの出し方

* [SnackBar](https://flutter.dev/docs/cookbook/design/snackbars#3-provide-an-optional-action)を使えばよい。

#### URLを開く

* [url_launcher](https://pub.dev/packages/url_launcher)を使う。（[参考](https://stackoverflow.com/a/43889379/14307339)）

	* `flutter pub add` した後のビルドで以下のエラーが出力されるが、管理者モードで起動したコマンドプロンプトでflutter runをすると以後は問題なくビルドできるようになった。（原因は深追いしていないが、[#66973](https://github.com/flutter/flutter/issues/66973)、[#72762](https://github.com/flutter/flutter/issues/72462)あたりが関係してそう）

		```
		Exception: Building with plugins requires symlink support. Please enable Developer Mode in your system settings.
		```

#### スクレイピング

* [universal_html](https://pub.dev/packages/universal_html)が安定していそう。
	* 参考
		* [FlutterでWebスクレイピング(QiitaのマイページからLGTMの数を取得)](https://qiita.com/toda-axiaworks/items/dd05264d5a7953316494)
		* [Flutterで基本的なスクレイピングをする方法](https://zenn.dev/7oh/articles/fe9fa855859011)

#### 画像ファイルのダウンロード・保存

* 参考：[Fetch data from Internet](https://flutter.dev/docs/cookbook/networking/fetch-data)

#### ウィンドウ幅に応じた折り返し表示

* [Wrap](https://api.flutter.dev/flutter/widgets/Wrap-class.html)で囲んであげればよい。（[参考](https://enjoy-a-lot.com/flutter-wrap/)）

#### 一部分のみスクロールバーを表示する

* [Expanded](https://api.flutter.dev/flutter/widgets/Expanded-class.html)の子要素に[SingleChildScrollView](https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html)を入れる。
	* WindowsだとScrollのthicknessを指定してもマウスオーバー時の影は細いままになる。（不具合かも。）
	* 参考：[flutterで一部だけスクロールさせたい](https://qiita.com/asosori2/items/8fb43cffcf18636be33f)

#### Containerにクリックイベントを設定する

* InkWellもしくはGestureDetectorを使う。
	* 参考：[Flutter: InkWell vs GestureDetector: what is the difference?](https://stackoverflow.com/questions/56725308/flutter-inkwell-vs-gesturedetector-what-is-the-difference)

#### OSのコマンドを実行する

* [Process.start()](https://api.flutter.dev/flutter/dart-io/Process-class.html) を使う。

#### SQLiteでデータを永続化する

* モバイル + MacOSでは[sqflite](https://pub.dev/packages/sqflite)が定番だが、Windows/Linuxでは[sqflite_common_ffi](https://pub.dev/packages/sqflite_common_ffi)を使えとのこと。
	* API仕様はsqfliteとほぼ同じのようなのでドキュメントは[ここ](https://pub.dev/documentation/sqflite_common/latest/sqlite_api/sqlite_api-library.html)を見ればよさそう。
	* ドキュメントには[リリースモードでは手動でsqlite3.dllを入れる必要あり](https://pub.dev/packages/sqflite_common_ffi#windows)、との記載があるが、入れなくてもちゃんと動いた。
	* 参考：[Persist data with SQLite](https://flutter.dev/docs/cookbook/persistence/sqlite)