• 全国 [切换]
  • 二维码
    晒展网

    手机WAP版

    手机也能找商机,信息同步6大终端平台!

    微信小程序

    微信公众号

    当前位置: 首页 » 行业新闻 » 热点新闻 » 正文

    Flutter 学习 之 主题设置 ThemeData

    放大字体  缩小字体 发布日期:2020-01-06 23:35:52   浏览次数:599  发布人:f449****  IP:106.39.94.***  评论:0
    导读

    基于ThemeData 实现主题切换 1. 实现可以亮暗主题切换2. 实现可以颜色主题的切换3.当主题为白色的时候替换一个其他主颜色4.当颜色为浅色时候需要做反色处理演示效果a5tnj-j7y0p.gif一. 修改Main.dark 文件//多Provider 当前只用了一个 为以后打基础return MultiProvider(providers: [ChangeNotifierProvide

    基于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**** 发布的作品,本文仅代表发布者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,发布者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们154208694@qq.com删除,我们积极做(权利人与发布者之间的调停者)中立处理。郑重说明:不 违规举报 视为放弃权利,本站不承担任何责任!
    有个别老鼠屎以营利为目的遇到侵权情况但不联系本站或自己发布违规信息然后直接向本站索取高额赔偿等情况,本站一概以诈骗报警处理,曾经有1例诈骗分子已经绳之以法,本站本着公平公正的原则,若遇 违规举报 我们100%在3个工作日内处理!
    0相关评论
     

    (c)2008-2022 展会信息发布,找展会,请上晒展网All Rights Reserved.