Flutter入門
Flutterとは
Flutterとは
- Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
特徴
- Fast development
- ホットリロードを始めとした、より高速に開発するための様々なツールが提供されている
- Expressive, beautiful UIs
- Material Design 等に沿ったUIパーツを使うことで、いい感じのUIが簡単に作れる
- Native Performance
- Dartという言語を使い、各プラットフォームに応じたネイティブコードを生成できる
なぜFlutterを使うのか?
- より高速に開発するため
- より魅力的なUI/UXを提供するため
アーキテクチャ・コンセプト
- 独自エンジンを各プラットフォームで動かせるようにしている
- エンジン内部にはUI描画処理も含まれている >> Skia
- ウィジェットのツリーでUIを表現
- Reactのような宣言的UIを採用している
Flutter for Web
iOS/AndroidだけでなくWebアプリの開発もサポートされている。
(2020年5月時点ではβ版)
Flutterでアプリを開発するには
Flutterを使ったアプリ開発の入門サイトがあるので、
こちらを利用してみましょう。
Androidアプリを起動してみる
Flutter導入
プロジェクト作成
// プロジェクト作成 w/ Integration tests $ flutter create --org com.umatoma --with-driver-test --no-pub flutter_training_app // そのままだと依存解決に失敗するので調整 $ vim pubspec.yaml - test: 1.6.2 + test: ^1.9.4 $ flutter pub get
アプリ起動
// 利用可能なエミュレータ一覧を確認 $ flutter emulators 3 available emulators: Pixel_3a_API_28 • Pixel 3a API 28 • Google • android TEST • TEST • • android apple_ios_simulator • iOS Simulator • Apple • ios ... $ flutter emulators --launch Pixel_3a_API_28 $ flutter run
テスト実行
// Unit tests 実行 // ファイル名が *_test.dart となっているものをテストファイルと認識する $ flutter test test/ 00:06 +1: All tests passed! // Integration tests 実行 // test_driver ディレクトリに target と同期したファイル名のテストが実行される // e.g. main.dart >> test_driver/main_test.dart $ flutter drive --target=./lib/main.dart Using device AOSP on IA Emulator. Starting application: ./lib/main.dart Installing build/app/outputs/apk/app.apk... 4.3s Running Gradle task 'assembleDebug'... Running Gradle task 'assembleDebug'... Done 13.2s ✓ Built build/app/outputs/apk/debug/app-debug.apk. ... 00:00 +0: end-to-end test (setUpAll) ... 00:01 +0: end-to-end test tap on the floating action button; verify counter 00:01 +1: end-to-end test (tearDownAll) 00:01 +1: All tests passed! Stopping application instance.
リリース用ビルド作成
// keystore 作成 $ keytool -genkey -v -keystore ./key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key // 署名用の設定を追加 $ vim android/app/build.gradle // apk 作成 $ flutter build apk You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64. ... Removed unused resources: Binary resource data reduced from 37KB to 32KB: Removed 14% Running Gradle task 'assembleRelease'... Running Gradle task 'assembleRelease'... Done 14.9s ✓ Built build/app/outputs/apk/release/app-release.apk (15.6MB).
Webアプリを起動してみる
Webアプリ機能有効化
// 現時点ではbeta版らしい $ flutter channel beta $ flutter config --enable-web // 作成済みのプロジェクトにWebアプリのコードを追加する場合 $ flutter create . Recreating project .... web/index.html (created) web/manifest.json (created) web/icons/Icon-192.png (created) web/icons/Icon-512.png (created) Wrote 7 files. ...
アプリ起動
$ flutter run -d chrome
リリース用ビルド作成
$ flutter build web
状態管理はどうやるのか
State
class MyWidget extends StatefulWidget { @override _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { int _count = 0; @override Widget build(BuildContext context) { return Container( child: RaisedButton( onPressed: () { setState(() { _count++; }); }, child: Text('Increment: $_count'), ), ); } }
Provider
void main() { runApp(ChangeNotifierProvider( create: (context) => CountModel(), child: MaterialApp( home: Column( children: <Widget>[ CounterText(), CounterButton(), ], ), ), )); } class CountModel extends ChangeNotifier { int _count = 0; int get count => _count; void increment() { _count++; notifyListeners(); } } class CounterText extends StatelessWidget { @override Widget build(BuildContext context) { // Consumer を通して Provider に渡したモデルにアクセスできる return Consumer<CountModel>( builder: (context, countModel, child) => Text('Count: ${countModel.count}'), ); } } class CounterButton extends StatelessWidget { @override Widget build(BuildContext context) { // データを参照する必要がない場合は Provider.of で listen:false でもOK final countModel = Provider.of<CountModel>(context, listen: false); return RaisedButton( onPressed: () => countModel.increment(), child: Text('Increment'), ); } }
ProviderはInheritedWidgetを使いやすくしたものである。
Providerの仕組みに関してはこちら↓で紹介
Widget
FlutterではUIを構築するための様々なWidgetが提供されている。
様々なWidgetを使ってみたい場合はこちら↓から
umatomakun.hatenablog.com umatomakun.hatenablog.com
感想
- 軽く使ってみた感じ、非常に簡単に環境構築〜アプリ作成まで行えるのが良い
- エディタを含め開発環境周りもそれなりに整っており、全体としての完成度が非常に高い印象
- Reactに影響されてそうな部分が多く、Reactユーザーにとっては参入障壁が低いはず
- テスト周りもデフォルトで Unit・Widget・Integration テストを行える環境が整備されていて良い
- バックエンドにDartを採用できれば、アプリ〜バックエンドまで少人数かつ1チームで全てを網羅することで出来る可能性も
- これができれば、規模が拡大してもFeatureチーム単位で組織を分割しやすくなる?
- ただし、各プラットフォームに関する知識をもっていないと、ハマった時に大変そう...