Flutter 的 MaterialApp
支援 Theme,可分別自訂 Light Mode 與 Dark Mode 的顏色。
Version
Flutter 3.24
Flutter
- Android 與 iOS 都成功顯示 Light Mode 與 Dark Mode
Main
main.dart
import 'package:flutter/material.dart';
import 'constants/dark_mode.dart';
import 'constants/light_mode.dart';
import 'home.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorScheme: lightMode,
),
darkTheme: ThemeData(
useMaterial3: true,
colorScheme: darkMode,
),
home: const Home());
}
}
- 建立
MyApp
widget 並傳入runApp()
顯示
Line 3
import 'constants/dark_mode.dart';
import 'constants/light_mode.dart';
- 引用
dark_mode
與light_mode
顏色設定常數
Line 14
build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorScheme: lightMode,
),
darkTheme: ThemeData(
useMaterial3: true,
colorScheme: darkMode,
),
home: const Home());
}
Widget
theme
:設定 light mode 主題dartTheme
:設定 dark mode 主題useMaterial3: true
:使用 Material 3colorScheme
:指定自行設定的lightMode
或darkMode
常數
Custom Color
constants/light_mode.dart
import 'package:flutter/material.dart';
var lightMode = const ColorScheme.light().copyWith(
primary: const Color(0xFFFF0000),
onPrimary: const Color(0xFFFFFFFF),
);
ColorSheme.light().copyWith()
:從內建 light mode 複製出預設色票,並加入新的自訂primary
與onPrimary
的顏色
constants/dark_moke.dart
import 'package:flutter/material.dart';
var darkMode = const ColorScheme.dark().copyWith(
primary: const Color(0xFF0000FF),
onPrimary: const Color(0xFFFFFFFF),
);
ColorSheme.dark().copyWith()
:從內建 dark mode 複製出預設色票,並加入新的primary
與onPrimary
的顏色
Counter
counter.dart
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({super.key});
State<Home> createState() {
return _Home();
}
}
class _Home extends State<Home> {
var _count = 0;
void _onPressed() {
setState(() => _count++);
}
Widget build(BuildContext context) {
var appBar = AppBar(title: const Text('Counter'));
var floatingActionButton = FloatingActionButton(
onPressed: _onPressed,
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
child: const Icon(Icons.add),
);
var body = Center(child: Text('$_count'));
return Scaffold(
appBar: appBar,
floatingActionButton: floatingActionButton,
body: body,
);
}
}
- 普通的 Stateful Widget 寫法
Line 23
floatingActionButton: FloatingActionButton(
onPressed: _onPressed,
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
child: const Icon(Icons.add),
),
backgroundColor
:由Theme.of(context)
取得目前是 light mode 或 dark mode,再從colorScheme
取得primary
顏色foregroundColor
:由Theme.of(context)
取得目前是 light mode 或 dark mode,再從colorScheme
取得onPrimary
顏色
Conclusion
- 實現自訂 light mode 與 dark mode 並不難,只要在自訂的
light_mode
與dark_mode
常數設定顏色
,且在最外層的MyApp
widget 的theme
與darkTheme
,且由Theme.of(context).colorScheme.primary
取得 Material Design 的顏色
Reference
Nidhi Sorathiya, Illuminating the Dark Canvas: The Definitive Guide to Implementing Flutter Dark Mode