點燈坊

失くすものさえない今が強くなるチャンスよ

自訂 Light Mode 與 Dark Mode

Sam Xiao's Avatar 2024-09-04

Flutter 的 MaterialApp 支援 Theme,可分別自訂 Light Mode 與 Dark Mode 的顏色。

Version

Flutter 3.24

Flutter

custom01

  • 在 light mode 與 dark mode 都可正常顯示

Main

main.dart

import 'package:flutter/material.dart';

import 'constants/dark_mode.dart';
import 'constants/light_mode.dart';
import 'counter.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: lightMode,
        ),
        darkTheme: ThemeData(
          useMaterial3: true,
          colorScheme: darkMode,
        ),
        home: const Counter());
  }
}
  • 建立 MyApp widget 並傳入 runApp() 顯示

Line 3

import 'constants/dark_mode.dart';
import 'constants/light_mode.dart';
  • 引用 dark_modelight_mode 顏色設定常數

Line 14


Widget build(BuildContext context) {
  return MaterialApp(
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: lightMode,
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorScheme: darkMode,
      ),
      home: const Counter());
}
  • theme:設定 light mode 主題
  • dartTheme:設定 dark mode 主題
  • useMaterial3: true:使用 Material 3
  • colorScheme:指定自行設定的 lightModedarkMode 常數

Custom Color

constants/light_mode.dart

import 'package:flutter/material.dart';

var lightMode = const ColorScheme.light().copyWith(
  primary: const Color(0xFF6200EE),
  secondary: const Color(0xFF03DAC6),
);
  • ColorSheme.light().copyWith():從內建 light mode 複製出預設色票,並加入新的自訂顏色

constants/dark_moke.dart

import 'package:flutter/material.dart';

var darkMode = const ColorScheme.dark().copyWith(
  primary: const Color(0xFFBB86FC),
  secondary: const Color(0xFF03DAC6),
);
  • ColorSheme.dark().copyWith():從內建 dark mode 複製出預設色票,並加入新的自訂顏色

Counter

counter.dart

import 'package:flutter/material.dart';

class Counter extends StatefulWidget {
  const Counter({super.key});

  
  State<Counter> createState() {
    return _Counter();
  }
}

class _Counter extends State<Counter> {
  var _count = 0;

  void _onPressed() {
    setState(() => _count++);
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter Demo')),
      floatingActionButton: FloatingActionButton(
          onPressed: _onPressed, child: const Icon(Icons.add)),
      body: Center(child: Text('$_count')),
    );
  }
}
  • 普通的 Stateful Widget 寫法,且不必再指定 light mode 與 dark mode 的顏色

Conclusion

  • 實現自訂 light mode 與 dark mode 並不難,只要在自訂的 light_modedark_mode 常數設定 顏色,且在最外層的 MyApp widget 的 themedarkTheme 設定一次即可

Reference

Nidhi Sorathiya, Illuminating the Dark Canvas: The Definitive Guide to Implementing Flutter Dark Mode