主题适配最好在新建项目时就考虑到

主题适配涉及到动态切换,需要用到状态管理。本项目用的是Provider

flutter pub add provider

创建主题文件

首先,创建 lib/pages/theme 文件夹

定义白天主题样式,创建light_theme.dart

theme/light_theme.dart
import 'package:flutter/material.dart';

ThemeData lightMode = ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.light(
primary: Colors.lightBlue,
onPrimary: Colors.white,
secondary: Colors.grey.withOpacity(0.25),
tertiary: const Color(0xFFEE4667),
inversePrimary: Colors.grey.shade600,
inverseSurface: Colors.grey.shade200,
onInverseSurface: Colors.grey.shade100,
surfaceContainer: Colors.grey.shade300,
),
);

定义夜间主题样式,创建dark_theme.dart

theme/dark_theme.dart
import 'package:flutter/material.dart';

ThemeData darkMode = ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.dark(
primary: Colors.blueAccent,
onPrimary: Colors.white,
secondary: Colors.grey.withOpacity(0.25),
tertiary: const Color(0xFFEE4667),
inversePrimary: Colors.grey.shade600,
inverseSurface: Colors.black87,
onInverseSurface: Colors.black26,
surfaceContainer: Colors.grey.shade300,
),
);

状态管理

创建theme_provider.dart文件

theme/theme_provider.dart
import 'package:e_book_clone/theme/dark_theme.dart';
import 'package:e_book_clone/theme/light_theme.dart';
import 'package:flutter/material.dart';

class ThemeProvider with ChangeNotifier {
ThemeData _themeData = lightMode;

ThemeData get themeData => _themeData;

set themeData(ThemeData themeData) {
_themeData = themeData;
notifyListeners();
}

bool get isDarkMode => _themeData == darkMode;
ThemeData get darkTheme => darkMode;
ThemeData get lightTheme => lightMode;

void toggleTheme() {
if (_themeData == lightMode) {
themeData = darkMode;
} else {
themeData = lightMode;
}
}
}

注册全局状态,修改main.dart

main.dart
import 'package:e_book_clone/app.dart';
import 'package:e_book_clone/theme/theme_provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
runApp(
MultiProvider(
providers: [
// 主题
ChangeNotifierProvider(create: (context) => ThemeProvider())
],
child: const MyApp(),
),
);
}

注册主题,修改app.dart

注意,增加darkTheme后,主题会跟随系统,这时theme不再生效

app.dart
...
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: designSize,
builder: (context, child) {
return MaterialApp(
theme: Provider.of<ThemeProvider>(context).themeData,
darkTheme: Provider.of<ThemeProvider>(context).darkTheme,
home: const HomePage(),
);
},
);
}
}

使用颜色代码

主题配置好之后如何使用呢?

通过Theme.of(context).colorScheme.来指定颜色

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

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

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
toolbarHeight: 0,
backgroundColor: Theme.of(context).colorScheme.surface,
surfaceTintColor: Theme.of(context).colorScheme.surface,
),
body: Center(
child: Text(
'Home',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 18.r,
),
)),
);
}
}