2.8K Views
March 07, 21
スライド概要
Mobile Act ONLINE #3
Flutterに 入門してみた 2021.2.19 Mobile Act ONLINE #3 itok@そらかぜ
itok@そらかぜ • • いとうけい(itok) の中の人 • モバイルアプリエンジニア 兼 CEO • 副業でフリーランス的 • https://itok.jp/, https://sorakaze.co.jp/, @itokjp
所在地:京都市中京区 社員1人=自分
実績 自社 受託
iOS / Android / macOS / Windows / サーバ 一人でやってます(デザイン以外)
言語・プラットフォーム歴 • 2002年〜 Objective-C • 2008年〜 iOS • 2013年〜 Android / Java • 2014年〜 Swift • 2016年〜 Kotlin • 2021年〜 Flutter ←イマココ(入門して3週間ほど
Flutterに 入門してみた
Flutterとは • Google製モバイルアプリフレームワーク(2017〜 • iOS / Android / Web のマルチプラットフォーム • 言語は Dart • https://flutter.dev/
比較 言語 Flutter React Native Xamarin Dart JaveScript C# API 独自 独自 独自 + wrapper UI 独自 ネイティブ ネイティブ 開発環境 Android Studio VS Code なんでも Visual Studio
構造
マルチプラットフォーム 🤔
🤔 • マルチプラットフォームって大丈夫なの? • 学習・導入コストは? • メンテナンスは? • トータルでは結局コストが余計にかかるとか?
そろそろ試してみる? 🤔
なぜFlutter? • 公開されて数年経ったし、安定してるかも • なんかまわりでは流行っている気がする • 勉強会ネタとして試してみるのはよさそう • 初心者ネタとして勉強会で発表して、いろいろと 教えてもらえたらいいなというスタイルで
とりあえず アプリ作ってみました
環境 • macOS 11.2.1 • Flutter 1.22.6 • Dart 2.10.5 • Android Studio 4.1.2 • Xcode 12.4
Diana
Diana • 位置情報に基づく月齢表示アプリ • 日英両対応 • もともと iOS - Swift / Android - Kotlin で実装 • Flutterでフルスクラッチ • v4.0.0リリース済み • https://moon.bz
入門前後で 気になった点などを 列挙していきます
Flutterの基本
Flutterの基本 • 宣言型のUI • Widgetの階層構造 • レイアウトもWidgetとして組み上げていく Widget _buildMoon(...) { return Container( child: AspectRatio( aspectRatio: 1, child: CustomPaint( painter: MoonPainter(...), ), ), ); }
Widgets
開発・デバッグ環境
開発・デバッグ環境 • 導入は簡単 • SDKの展開 & 設置 • Android Studioのプラグイン導入→完了👍 • Hot reloadあり • Android Studioから直接デバッグできる • iOSもAndroidもどちらも
Continuous Integration
Continuous Integration • 著名どころはだいたい対応 • Fastlane • Bitrise • GitHub actions
プラットフォーム 依存部分
プラットフォーム依存部分 • 各packageで対応( https://pub.dev ) • 公式・非公式さまざま • 主要なものはだいたいある • 位置情報、カメラ、写真ライブラリなど
例)位置情報取得 import 'package:location/location.dart'; Future<LocationData> _getLocationData() async { Location location = Location(); bool serviceEnabled = await location.serviceEnabled(); if (!serviceEnabled) { serviceEnabled = await location.requestService(); if (!serviceEnabled) { return null; } } PermissionStatus permissionGranted = await location.hasPermission(); if (permissionGranted == PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != PermissionStatus.granted) { return null; } } return await location.getLocation(); }
デザイン
デザイン • 基本的にはMaterialデザイン • • プラットフォーム間で共通 iOS風のCupertino widget群もある • 両デザインを実行時に切り替える packageもある
iOS風 Switch CupertinoSwitch PlatformSwitch (flutter̲platform̲widgets)
タブレット (adaptive)
タブレット(adaptive) • 画面サイズをみて自前で調整する必要あり LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { if (constraints.maxWidth < constraints.maxHeight) { return _portraitLayout(moonBox, dataTableBox); } else { return _landscapeLayout(moonBox, dataTableBox); } } )
ダークモード
ダークモード • Theme / ThemeDataで対応 Widget build(BuildContext context) { return MaterialApp( theme: ThemeData.light(), darkTheme: ThemeData.dark(), ...); }
ローカライズ
ローカライズ • iOS / Android両対応可能 { { "moon": "Moon", "@moon": {}, "newMoon": "New", "@newMoon": {}, "moon": "月", "newMoon": "新月", ... ... Text(AppLocalizations.of(context).moon)
広告
広告 • AdMobなど一部のSDKについてはpackageあり
まとめ
まとめ • 気になりポイント • ネイティブUI感は薄い(特にiOS)←逆にOSの 変更で動かなくなることは少なそう? • OS独自(あるいは外部SDK)の新しいAPIをす ぐに使えるわけではない
まとめ • • とはいえ • 適材適所ではあるが開発の選択肢としては十分に可能 性あり • iOS / Androidの開発経験があるとなおよさそう 公式ドキュメント( https://flutter.dev/docs )が充 実しているから最終的にはそこを見るべし • "flutter" のgoogleabilityが高いのは助かる (もう少し探求してみるかも)