热点新闻
Flutter 学习 之 主题设置 ThemeData
2023-07-04 23:35  浏览:2979  搜索引擎搜索“手机晒展网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在手机晒展网看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

基于ThemeData 实现主题切换
1. 实现可以亮暗主题切换
2. 实现可以颜色主题的切换
3.当主题为白色的时候替换一个其他主颜色
4.当颜色为浅色时候需要做反色处理

演示效果





a5tnj-j7y0p.gif

一. 修改Main.dark 文件

//多Provider 当前只用了一个 为以后打基础 return MultiProvider( providers: [ ChangeNotifierProvider<ThemeViewModel>( create: (context) => ThemeViewModel(), ), ], child: Consumer<ThemeViewModel>( builder: (context, themeProvider, Widget? child) { return MaterialApp( ///title android用来在多任务上显示昵称用的 title: 'Flutter Theme Demo', //首页 home: const MyHomePage(), //明亮的主题 theme: themeProvider.getTheme(), //夜间模式 darkTheme: themeProvider.getTheme(isDarkMode: true), //当前主题模式 themeMode: themeProvider.getThemeMode(), ); }, ), );

二.定义 theme_provider.dart

  • 先拓展一下ThemeData 好通过SP保存

extension ThemeModeExitension on ThemeMode { String get value => <String>['System', 'Light', 'Dark'][index]; }

  • 创建类

class ThemeViewModel extends ChangeNotifier { ///主题模式 亮色 暗色 跟随系统 ThemeMode? _themeMode; //亮色主题色 late MaterialColor _themeColor; //暗色主题色 final MaterialColor _themeDarkColor= ColorUtil.createMaterialColor(ColorConfig.darkBGColor); ThemeViewModel() { Color primaryColor=Colors.white; //设定一个初始颜色 //如果由保存颜色则替换颜色 String? color = CacheUtil().get<String>(SPName.themeColor); if (color != null) { //把存储的#RRGGBB颜色转换十六进制的0xFF格式的 primaryColor = ColorUtil.hexToColor(color); } _themeColor = ColorUtil.createMaterialColor(primaryColor); } get selectColor => isDark() ? _themeDarkColor : _themeColor; bool isDark() { //如果当前是跟随系统那么判定当前系统是不是暗色模式 if (_themeMode == ThemeMode.system) { return SchedulerBinding.instance?.window.platformBrightness == Brightness.dark; } return _themeMode == ThemeMode.dark; } //获取当前主题模式 ThemeMode getThemeMode() { String? themeModel = CacheUtil().get<String>(SPName.themeMode); switch (themeModel) { case "Dark": _themeMode = ThemeMode.dark; break; case "System": _themeMode = ThemeMode.system; break; default: _themeMode = ThemeMode.light; break; } return _themeMode!; } //获取保存的主题颜色 Color getThemColor() { String? color = CacheUtil().get<String>(SPName.themeColor); return _themeColor = ColorUtil.createMaterialColor(ColorUtil.hexToColor(color)); } ///设置主题 set them(ThemeMode themeMode) { CacheUtil().setString(SPName.themeMode, themeMode.value); _themeMode = themeMode; notifyListeners(); } ///设置主题颜色 set themeColor(Color color) { CacheUtil().setString(SPName.themeColor, ColorUtil.color2HEx(color)); _themeColor = ColorUtil.createMaterialColor(color); them=ThemeMode.light; } /// 获取主题 ThemeData getTheme({bool isDarkMode = false}) { var themeData = ThemeData( brightness: isDarkMode ? Brightness.dark : Brightness.light, //错误颜色 errorColor: Colors.red, //主题色 primaryColor: isDarkMode ? _themeDarkColor : _themeColor, //浅主题色 primaryColorLight: isDarkMode ? _themeDarkColor[50] : _themeColor[50], //深主题色 primaryColorDark: isDarkMode ? _themeDarkColor[700] : _themeColor[700], // Tab指示器的颜色 如果当前主题色是白色 那么指点杆的颜色指定为另一个 indicatorColor: isDarkMode ? ColorConfig.darkBtnColor : ColorUtil.isWhiteColor(_themeColor) ? ColorConfig.lightBtnColor : _themeColor, // 页面背景色 scaffoldBackgroundColor: isDarkMode ? ColorConfig.darkBGColor : ColorConfig.lightBGColor, //开关 单选和多选按钮选中效果 toggleableActiveColor: isDarkMode ? ColorConfig.darkBtnColor : ColorUtil.isWhiteColor(_themeColor) ? ColorConfig.lightBtnColor : _themeColor, //progressIndicator 的背景颜色 progressIndicatorTheme: ProgressIndicatorThemeData( color: isDarkMode ? ColorConfig.darkBtnColor : ColorUtil.isWhiteColor(_themeColor) ? ColorConfig.lightBtnColor : _themeColor, ), // textButtonTheme: TextButtonThemeData(style: ButtonStyle(MaterialStateProperty.all())), //Material 组件默认使用这个颜色 如果没配置则是一个蓝色 primarySwatch: isDarkMode ? _themeDarkColor : _themeColor, //大部分的ListTile 控件都会用到 除了 ExpansionTile 他会覆盖一部分组件样式 listTileTheme: ListTileThemeData( selectedTileColor: Colors.blue, iconColor: isDark() ? ColorConfig.darkBtnColor : ColorUtil.isLightColor(_themeColor) ? ColorConfig.lightBtnColor : _themeColor, ), //icon的主题设置 iconTheme: IconThemeData( color: isDarkMode ? ColorConfig.darkBtnColor : ColorUtil.isWhiteColor(_themeColor) ? ColorConfig.lightBtnColor : _themeColor, size: 16), // textButtonTheme:TextButtonThemeData() , //具体组件的颜色配置 appBarTheme: AppBarTheme( backgroundColor: isDarkMode ? _themeDarkColor : _themeColor, elevation: 0, centerTitle: true, titleTextStyle: TextStyle( color: isDark() ? ColorConfig.dartH1Color : ColorUtil.isLightColor(_themeColor) ? Colors.black : Colors.white, fontSize: 20), ), //具体文字的颜色配置 textTheme: TextTheme( //ListTitle中的Title用到 subtitle1: TextStyle( color: isDarkMode ? ColorConfig.dartH1Color : ColorConfig.lightH1Color, fontSize: 18), subtitle2: TextStyle( color: isDark() ? ColorConfig.dartH1Color : ColorUtil.isLightColor(_themeColor) ? Colors.black : Colors.white, fontSize: 16), //用在非Material组件上的文字显示, bodyText1: TextStyle( color: isDarkMode ? ColorConfig.dartH2Color : ColorConfig.lightH2Color, fontSize: 16), //Material组件上的文字显示 bodyText2: TextStyle( color: isDarkMode ? ColorConfig.dartH2Color : ColorConfig.lightH2Color, fontSize: 16), //ListTitle的副标题用这个颜色 caption: TextStyle( color: isDarkMode ? ColorConfig.dartH3Color : ColorConfig.lightH3Color, fontSize: 14), button: TextStyle( color: isDarkMode ? ColorConfig.darkBtnColor : ColorUtil.isWhiteColor(_themeColor)?ColorConfig.lightBtnColor:_themeColor, fontSize: 16), )); return themeData; } }

三.在另一界面的使用

  • 创建ViewModel

class HomePageViewModel extends baseViewModel { //创建模式选择 List<Map<String, dynamic>> modelItem = [ {"name": '跟随系统', "mode": ThemeMode.system}, {"name": '白天模式', "mode": ThemeMode.light}, {"name": '夜间模式', "mode": ThemeMode.dark}, ]; //创建主题颜色 List<String> colorList = [ "#FFFFFF", "#843900", "#905d1d", "#b3424a", "#181d4b", "#d9d6c3", "#281f1d", "#ffeb3b", "#2A2C37", "#00FA9A", "#009ACD", ]; //当前的模式 ThemeMode? selectModel; //上下文 BuildContext? context; //选择的颜色 Color? selectColor; //themeViewModel var provider; //切换模式 void changeModel(value) { provider.them = value; selectModel = value; notifyListeners(); } //切换颜色 void onChangeColor(String colorStr) { Color col = ColorUtil.hexToColor(colorStr); ThemeMode mode = ThemeMode.light; //如果切换的颜色是夜间模式 那么直接切换模式 if (col == ColorConfig.darkBGColor) { mode = ThemeMode.dark; changeModel(mode); } else { provider.themeColor = col; } selectColor = col; selectModel = mode; notifyListeners(); } //初始化加载 onLoad(context) { this.context = context; provider = Provider.of<ThemeViewModel>(context); selectModel = provider.getThemeMode(); selectColor = provider.getThemColor(); setIdly(); } }

详细使用详见源码

四. 使用到的颜色工具类

import 'dart:ui'; import 'package:flutter/material.dart'; class ColorUtil{ ///判断一个颜色是否是亮色 用来判断反色 static bool isLightColor(Color color){ double darkness = 1 - (0.299 * color.red + 0.587 * color.green + 0.114 * color.blue) / 255; return darkness<0.5; } //判断它是不是白色 static bool isWhiteColor(Color color){ return color.value.toRadixString(16) == "ffffffff"; } /// Construct a color from a hex code string, of the format #RRGGBB. static Color hexToColor(String? code) { if (code==null||code==""|| code.length != 7) { return Colors.blue; } return Color(int.parse(code.substring(1, 7), radix: 16) + 0xFF000000); } ///创建Material风格的color static MaterialColor createMaterialColor(Color color) { List strengths = <double>[.05]; Map swatch = <int, Color>{}; final int r = color.red, g = color.green, b = color.blue; for (int i = 1; i < 10; i++) { strengths.add(0.1 * i); } for (var strength in strengths) { final double ds = 0.5 - strength; swatch[(strength * 1000).round()] = Color.fromRGBO( r + ((ds < 0 ? r : (255 - r)) * ds).round(), g + ((ds < 0 ? g : (255 - g)) * ds).round(), b + ((ds < 0 ? b : (255 - b)) * ds).round(), 1, ); } return MaterialColor(color.value, swatch as Map<int, Color>); } /// 颜色检测只保存 #RRGGBB格式 FF透明度 /// [color] 格式可能是材料风/十六进制/string字符串 /// 返回[String] #rrggbb 字符串 static String? color2HEx(Object? color) { if (color is Color) { // OxFFFFFFFF //将十进制转换成为16进制 返回字符串但是没有0x开头 String temp = color.value.toRadixString(16); color = "#" + temp.substring(2, 8); } return color.toString(); } }

源码地址:链接:https://pan.baidu.com/s/1iip8W3jy0YmWqMIaLhih5Q
提取码:xisr

发布人:f449****    IP:106.39.94.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发