Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter_Kaigi_miyake.pdf

Ryo Miyake
November 18, 2022

 Flutter_Kaigi_miyake.pdf

本気でDarkModeに対応する

"Flutter DarkMode" で検索すると大体こう書かれてます。
「ダークテーマを用意して切り替えましょう」
そのとおりですね。まったく間違ってないです。さあダークテーマを用意しましょう。

さて、デザイナーさんから渡されたFigmaやXDには何が書かれてるでしょうか。

DarkModeの場合はこちらのアイコンを使ってください
この画面はLightModeとDarkModeの違いがありません
エラーメッセージの色は #EF5353 DarkModeの場合は #FC7463 です
このボタンのテキストカラーは #FFFFFF です
このボタンのテキストカラーは #333333 DarkModeの場合は #FFFFFF です
このトーストのカラーは...
困りましたね。テーマにはそんな細かな設定がありません。もしかしたらあるかもしれませんがひとつずつ調べるのは大変です。

そんな困ったときの、ひとつの解決方法をお話しようかと思います。

Ryo Miyake

November 18, 2022
Tweet

More Decks by Ryo Miyake

Other Decks in Programming

Transcript

  1. ©10X, Inc. All Rights Reserved. 2 Dark Mode って必要?
 ※

    Android では Dark Theme っていいます
  2. ©10X, Inc. All Rights Reserved. 個人的には、なくてもいい
 3 • 黒い画面怖い
 •

    実装が面倒
 • 生鮮食品購入するのに暗いとかないわ
 
 (ネットスーパーの場合)
  3. ©10X, Inc. All Rights Reserved. どういうアプリでDarkModeが欲しい?
 4 • エンジニアが使うエディタ
 ◦

    VS Code,Android Studio, IntelliJ IDEA
 • 暗い部屋でだらだら見るアプリ
 ◦ SNS,ニュース,Kindle,動画アプリはDarkModeだけでいい

  4. ©10X, Inc. All Rights Reserved. まずはテーマを用意しましょう 6 Darkテーマ ミニマムだとたったこれだけ Default

    が system なので省略可 普通のLightテーマ OSの設定で勝手に切り替わります
  5. ©10X, Inc. All Rights Reserved. 影響範囲が分かる範囲でテーマをカスタマイズします
 7 iconTheme, textTheme, appBarTheme,

    buttonTheme…
 テーマの名前から想像したり、各Widgetのソースコードを読んでみたりして、 「あぁ、このテーマがここに影響するのね。」みたいに言いながら設定するの がいいんじゃないですか。

  6. ©10X, Inc. All Rights Reserved. テーマだけで足りるか?
 8 
 タイトル,説明文,日付
 複数のテキスト複数のStyleがある場合どうする?


    
 TextThemeで使い分けるのがいい
 • タイトル:textTheme.titleSmall
 • 説明文:textTheme.bodyMedium
 • 日付:textTheme.caption
 いけそう...

  7. ©10X, Inc. All Rights Reserved. やっぱりテーマだけでは足りない
 9 
 • エラーメッセージはこの色ね


    ◦ Lifghtは #EF5353 で DarkModeの場合は #FC7463 です
 • Disableのときはこっちの色で
 • 検索にマッチしてたら背景をハイライトカラーにして
 • URLはリンクなのでこの色で
 ◦ 一回踏んだリンクはこっちの色ね
 • DarkModeのときはこっちのアイコンで
 ◦ SVGで表現できなったからPNGにしたよ
 もう無理。頑張ったらギリギリできるかもしれんけど無理

  8. ©10X, Inc. All Rights Reserved. 独自のテーマクラスを作りましょう
 10 • static で

    light と dark を定義するとよい
 • Color以外にもAssetPathの文字列でも何でもOK
 • extensionを作るとtextTheme等と同じような感じで使えます
 • final oreTheme = Theme.of(context).oreTheme; • Themeが切り替わると一緒にOreThemeも切り替わります
 これで終わりでもいいんだけど...
  9. ©10X, Inc. All Rights Reserved. ThemeExtensionって
 11 • Flutter3からはThemeExtensionがつかえる
 •

    Themeの中に独自のテーマクラスを加えられる
 • ThemeData.extensionsに設定する
 
 • final oreTheme = Theme.of(context).extension<OreThemeData>()!; で利用できる
 
 extensionsに設定 ※ThemeData.from では使えないのでここではcopyWithを使ってる
  10. ©10X, Inc. All Rights Reserved. ThemeExtensionって
 12 • ThemeExtensionを継承する
 •

    copyWith と lerp を実装する
 • extensionを作るとtextTheme等と同じような感じで使えます
 • final oreTheme = Theme.of(context).oreTheme; 
 copyWith と lerp ちょっと面倒
  11. ©10X, Inc. All Rights Reserved. アプリ内でModeを切り替えたい
 13 • ThemeMode の設定画面を作る

    • SharedPreferences 等に保存する • ChangeNotifier 等で MaterialApp の themeMode を切り替える
  12. ©10X, Inc. All Rights Reserved. SystemNavigationBarを透過したい
 17 • SafeArea の

    bottom が Bar の高さだけ大きくなります。 
 • 個人的には、3つボタンのときは透過するの好きじゃない 

  13. ©10X, Inc. All Rights Reserved. 3つボタンかどうかって?
 19 • Flutter だけで調べる方法がわからなかった

    
 • Android の Resources から NavigationBar の高さを取得することはできる 
 • これを density で割って40以上なら3つボタンとかでよさそう 
 • コードは長いのでここに置いてます 
 https://github.com/miyakeryo/flutter_kaigi_2022 

  14. ©10X, Inc. All Rights Reserved. まとめ
 20 • DarkMode 対応は我々にとって必要

    
 • OreThemeData を ThemeData の extension にするのが簡単 
 • ThemeExtension はちょっと面倒なのでlerp省略が楽 
 • Android の SystemNavigationBar にこだわり始めると大変 
 • https://github.com/miyakeryo/flutter_kaigi_2022