type
status
date
slug
summary
tags
category
icon
password
这些年,移动端UI的深色模式还是比较常见你的,IOS在系统级别已经率先支持了,Flutter作为一款优秀的跨端UI框架,在处理深色模式上是比较简单的。
notion image

Brightness

Flutter中有一个Brightness的概念,用来表示主题和颜色的亮暗模式。
enum Brightness { /// The color is dark and will require a light text color to achieve readable /// contrast. /// /// For example, the color might be dark grey, requiring white text. dark, /// The color is light and will require a dark text color to achieve readable /// contrast. /// /// For example, the color might be bright white, requiring black text. light, }
Flutter针对主题也提供了封装:
factory ThemeData.light() => ThemeData(brightness: Brightness.light); factory ThemeData.dark() => ThemeData(brightness: Brightness.dark);
访问方式如下:
final lightTheme = ThemeData.light(); final dartTheme = ThemeData.dark();
我们首先想一下,要实现一个切换深色主题的功能的步骤是什么?
  1. 设置页:进行浅色/深色模式切换,并进行持久化,以便app重启之后还是生效的;
  1. App:启动的时候获取持久化的浅色/深色模式,并应用到app的主题上;
  1. 切换时实时刷新主题的深浅模式;

1. 进行深浅色模式的切换

<img src="https://oss.jiangkang.tech/jk/shense2.png" style="zoom:50%;" />
这里使用SharedPreferences来进行持久化,代码比较简单:
import 'package:flutter/material.dart'; import 'package:flutter_system/constants/const_key_value.dart'; import 'package:flutter_system/theme/custom_themes.dart'; import 'package:flutter_system/utils/sp_utils.dart'; import 'package:provider/provider.dart'; /// 设置页 class SettingsPage extends StatefulWidget { @override _SettingsPageState createState() => _SettingsPageState(); } class _SettingsPageState extends State<SettingsPage> { bool _isDarkMode = false; @override void initState() { SpUtils.getBool(keyIsDarkMode, false).then((value) { setState(() { _isDarkMode = value; }); }); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("设置页"), centerTitle: true, ), body: SafeArea( child: ListView( children: <Widget>[ SwitchListTile( title: Text("深色模式"), value: _isDarkMode, onChanged: (newValue) { setState(() { SpUtils.saveBool(keyIsDarkMode, newValue); _isDarkMode = newValue; Provider.of<ThemesNotifier>(context) .setCurrentTheme(newValue ? dartTheme : lightTheme); }); }, activeColor: Theme.of(context).accentColor, ), ], )), ); } }

App启动时获取持久化的深浅色模式

SpUtils.getBool(keyIsDarkMode, false).then((value) { Provider.of<ThemesNotifier>(context, listen: false) .setCurrentTheme(value ? dartTheme : lightTheme); });

深浅色模式改变时,实时刷新APP

从前面的两段代码可以看出,我们使用了Provider。
这里我们可以把Provider当做一个单例模式,一处改变,全局生效。
class _MyAppState extends State<MyApp> { @override void initState() { SpUtils.getBool(keyIsDarkMode, false).then((value) { Provider.of<ThemesNotifier>(context, listen: false) .setCurrentTheme(value ? dartTheme : lightTheme); }); super.initState(); } @override Widget build(BuildContext context) { final themeProvider = Provider.of<ThemesNotifier>(context); return MaterialApp( title: 'Flutter System', theme: themeProvider?.currentTheme ?? lightTheme, debugShowCheckedModeBanner: false, initialRoute: '/', routes: pageRouters, localizationsDelegates: [ S.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: S.delegate.supportedLocales, ); } }

源码

Flutter-TimelineFlutter时间处理
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏