Save 37% off PRO during our Black Friday Sale! »

TechCon Official App on Flutter

TechCon Official App on Flutter

73e023e76c881293c494a350b1b7baa2?s=128

Katsumi Onishi

January 30, 2019
Tweet

Transcript

  1. TechCon Official App on Flutter Katsumi Onishi Android Engineer 株式会社ディー・エヌ・エー

    @katsummy
  2. 目次 2 DeNA TechCon 2019 Why Flutter ? What New

    Challenged? Review 1 3 Appendix 4 2
  3. 3

  4. 4 DeNAでは、ゲームやエンタメだけでなく、 Eコマース、ソーシャルLIVE、ヘルスケア、オートモーティブ、 そして横浜DeNAベイスターズのようなスポーツなど、様々な事業を行っています。 また、技術の力で事業の未来をリードするため、様々なチャレンジも行っています。 DeNA TechCon はこれらのチャレンジの中から、 技術的に特に面白いものを厳選して皆さんにお披露目するお祭りです。

  5. 5 今年のテーマは「SHIFT UP」です。 『面白かったー!』と思っていただく工夫を凝らしてお待ちしてますので、 みなさまぜひお越しください!

  6. 6 12月中旬... Why Flutter ?

  7. Why Flutter ? • 12月中旬... • DeNA TechApp 2019 2.6

    開催にあたりオフィシャルアプリを作成した い • iOS / Android 両方でリリースしたい • 短納期なのでハイブリッド? • 先日、Flutter 1.0 リリースされた!! • Flutter Live '18 at 4.Nov in London • 新しい技術にチャレンジ! 7
  8. What New Challenged? • DeNA の Flutter アプリは初めて • どうせなら普段のアプリできないことをやりたい

    • マテリアルデザインの新しいコンポーネントを使用 • Backdrop • Flareでアニメーション • PlatformView で Google Map を表示 • 新しいソフトウェアアーキテクチャ • Redux 8
  9. What New Challenged? • マテリアルデザインの新しいコンポーネントを使用 • Backdrop - Material Design

    9 Back layer Front layer Subheader
  10. Backdrop 10

  11. Timetable with Fixed Header 11

  12. Timetable with Fixed Header 12 Stack Custom ScrollView Custom ScrollView

    SliverAppBar SliverFixedExtentList ListView ListView タイムテーブルのViewの縦スク ロールを時間のViewにSync
  13. FLARE • 2Dimensions社無償公開の2Dのベクターアニメーションツール • エクスポートしたアニメーションをそのままFlutterで再生が可能 13

  14. FLARE • Splash 14 2D - denaxtech - Logo

  15. FLARE child: Center( child: FlareActor( "assets/animations/Logo.flr", animation: _animationName, fit: BoxFit.contain,

    callback: (string) { Navigator.of(context) .pushReplacementNamed(AppRoutes.home); }, ), ), 15
  16. PlatformView で Google Map • 組み込みは簡単 • google_maps_flutter を使用 •

    Android のみ実装 • iOS 挙動不安定... • Backdropの影響? 16
  17. TechCon Official App 17 16:9

  18. What New Challenged? • アーキテクチャー • MultiModule • Flutterでもできる •

    Redux (Flux) 18 App Architecture (Redux) Repository Common Repository Impl
  19. MultiModule 19

  20. MultiModule <pubspec.yaml> dependencies: flutter: sdk: flutter commons: path: ../commons architecture:

    path: ../architecture repository: path: ../repository repository_cache: path: ../repository_cache 20
  21. Redux • 採用箇所 • Backdrop / TimeTable 21 isLoading activeTab

  22. Store Redux 22 Action Widget Middleware Repository State Reducer State

    ViewModel Dispatch
  23. Redux class App extends StatelessWidget { /// Store final Store<AppState>

    store = Store<AppState>( appReducer, initialState: AppState.initial(), middleware: createStoreMiddleware(RepositoryCache()), ); @override Widget build(BuildContext context) { return StoreProvider<AppState>( store: store, child: MaterialApp( 23
  24. Redux /// Reducer final appReducer = combineReducers<AppState>([ TypedReducer<AppState, LoadingAction>(_onLoading), TypedReducer<AppState,

    ErrorAction>(_onError), TypedReducer<AppState, SessionsLoadAction>(_onLoadSessions), TypedReducer<AppState, SessionsLoadedAction>(_onLoadedSessions), TypedReducer<AppState, UpdateTabAction>(_onUpdateTab), ]); 24
  25. Redux @immutable class AppState { final bool isLoading; final bool

    hasError; final AppTab activeTab; final List<Session> sessions; 25
  26. Redux /// Middleware List<Middleware<AppState>> createStoreMiddleware(Repository repository) { _repository = repository;

    return [ TypedMiddleware<AppState, SessionsLoadAction>(_load), ]; } 26
  27. Redux /// Sessions Load Future _load(Store<AppState> store, action, NextDispatcher next)

    async { // Dispatch a LoadingAction to show a loading spinner store.dispatch(LoadingAction()); // Get session var sessions = await _repository.getSessionList(); store.dispatch(SessionsLoadedAction(sessions)); next(action); } 27
  28. Redux class TimeTablePage extends StatelessWidget { @override Widget build(BuildContext context)

    { return StoreConnector<AppState, _ViewModel>( onInit: (store) => store.dispatch(SessionsLoadAction()), distinct: true, converter: _ViewModel.fromStore, builder: (context, vm) { if (vm.isLoading) { return Center(child: LoadingIndicator()); } else { return TimeTable( sessions: vm.sessions, ); } }, 28
  29. • TimeTableWidget は力技感.... • Redux • View と Logicの分離 •

    State は Storeで一元管理 • View毎に StoreからViewModelを作成が若干手間 • Middleware内でdispatchさせるとnextのactionは...? • 小規模アプリでは... Review 29
  30. • 課題 • FCM • 通知 の アプリ内表示 • LicensePage

    • 内容に重複が多く法務確認が手間 • Flutter Engineのライセンスまで表示される... • skia で使用している gif ライブラリが MPL 1.1/GPL 2.0/LGPL 2.1 トリプルライセンスであるが、LGPL 2.1 のみ表示される。 • CI • [Jan 23, 2019] Flutter CI v.1.0.0 がBitriseに登場! • もっとはやくに... Review 30
  31. Appendix 31 ソースコードは公開します! will soon 詳しくはGitHubで!

  32. 32 テックコン 検索 ブースも出 します!