🍆

Flutterダークモード・ライトモード

2024/10/22に公開

以前書いた記事が微妙なので端末の状態で色を変えることにした

以前は端末にダークモード・ライトモードの状態を記録する記事を書きました。

https://zenn.dev/joo_hashi/articles/e7567ed95d69ff

しかし端末の設定を変更して色が白と黒に変わるでしょうからこれ意味あるのと思いました。SwiftUIで苦い経験をしまして? :(三項演算子)でダークモード・ライトモードへの対応をするユースケースがありました。

Flutterでも同じことをしようと思った。command + shift + AキーでiOSのシュミレータをダークモード・ライトモードに切り替えることはできます。

iPhone

https://youtu.be/cBAudbn8CPA

Android

https://youtu.be/fKlL5d_0p9Y

ソースコードはこちら

main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Theme Mode Demo',
      // システムの設定に従うように設定
      themeMode: ThemeMode.system,
      // ライトモードのテーマ設定
      theme: ThemeData(
        brightness: Brightness.light,
        primaryColor: Colors.blue,
        scaffoldBackgroundColor: Colors.white,
        textTheme: const TextTheme(
          bodyLarge: TextStyle(color: Colors.black),
        ),
      ),
      // ダークモードのテーマ設定
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        primaryColor: Colors.blueAccent,
        scaffoldBackgroundColor: Color(0xFF303030),
        textTheme: const TextTheme(
          bodyLarge: TextStyle(color: Colors.white),
        ),
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  
  Widget build(BuildContext context) {
    // 現在のテーマモードを取得
    final isDarkMode = Theme.of(context).brightness == Brightness.dark;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Theme Mode Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Current theme mode: ${isDarkMode ? "Dark" : "Light"}',
              style: Theme.of(context).textTheme.bodyLarge,
            ),
            const SizedBox(height: 20),
            const Text(
              '端末の設定に応じてテーマが自動的に切り替わります',
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
    );
  }
}

ライトモード

ダークモード

最後に

設定方法は他にもあるようです。内部実装みてみたのですがこんなこと書いてありましたよThemeDataってfactoryコンストラクタなのかな?

/// * [ThemeData.from], which creates a ThemeData from a [ColorScheme].
/// * [ThemeData.light], which creates a light blue theme.
/// * [ThemeData.dark], which creates dark theme with a teal secondary [ColorScheme] color.
/// * [ColorScheme.fromSeed], which is used to create a [ColorScheme] from a seed color.
factory ThemeData({
// For the sanity of the reader, make sure these properties are in the same
// order in every place that they are separated by section comments (e.g.
// GENERAL CONFIGURATION). Each section except for deprecations should be
// alphabetical by symbol name.

/// * [ColorScheme]からThemeDataを作成する[ThemeData.from]。
/// * [ThemeData.light]: ライトブルーのテーマを作成します。
/// * [ThemeData.dark]: [ColorScheme]の二次色がティール色のダークテーマを作成します。
/// * [ColorScheme.fromSeed]は、シードカラーから[ColorScheme]を作成するために使用されます。
factory ThemeData({
これらのプロパティが配置されるすべての場所で // 同じ順序であることを確認してください。
// これらのプロパティがセクションコメントで区切られているすべての場所で同じ順序であることを確認してください(例
// 一般的な設定など)。非推奨を除く各セクションは
// シンボル名のアルファベット順。

朝活してたときは、WidgetsBindingObserver class なるものを試していましたがこれを使うまでもなかったかもしれない。

Discussion