当前位置: 首页 > news >正文

6.1 主题与暗色模式

Flutter 的主题系统(ThemeData)提供了统一的视觉风格管理,通过 Material 3 的颜色系统和深色模式支持,可以轻松构建专业的视觉体系。


一、ThemeData 动态切换

1.1 定义双主题

classAppTheme{// 亮色主题staticThemeDatagetlightTheme=>ThemeData(useMaterial3:true,brightness:Brightness.light,colorScheme:ColorScheme.fromSeed(seedColor:constColor(0xFF6750A4),// 主色调brightness:Brightness.light,),// 文字主题textTheme:_buildTextTheme(Brightness.light),// 组件主题appBarTheme:constAppBarTheme(centerTitle:true,elevation:0,),cardTheme:CardTheme(elevation:2,shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(12)),),elevatedButtonTheme:ElevatedButtonThemeData(style:ElevatedButton.styleFrom(minimumSize:constSize.fromHeight(48),shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(12)),),),inputDecorationTheme:InputDecorationTheme(border:OutlineInputBorder(borderRadius:BorderRadius.circular(12),),filled:true,),);// 暗色主题staticThemeDatagetdarkTheme=>ThemeData(useMaterial3:true,brightness:Brightness.dark,colorScheme:ColorScheme.fromSeed(seedColor:constColor(0xFF6750A4),brightness:Brightness.dark,),textTheme:_buildTextTheme(Brightness.dark),appBarTheme:constAppBarTheme(centerTitle:true,elevation:0),cardTheme:CardTheme(elevation:4,shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(12)),),);staticTextTheme_buildTextTheme(Brightnessbrightness){finalcolor=brightness==Brightness.light?constColor(0xFF1C1B1F):constColor(0xFFE6E1E5);returnTextTheme(headlineLarge:TextStyle(fontSize:32,fontWeight:FontWeight.bold,color:color),headlineMedium:TextStyle(fontSize:24,fontWeight:FontWeight.bold,color:color),titleLarge:TextStyle(fontSize:20,fontWeight:FontWeight.w600,color:color),bodyLarge:TextStyle(fontSize:16,color:color),bodyMedium:TextStyle(fontSize:14,color:color.withOpacity(0.8)),);}}

1.2 主题切换控制器

classThemeControllerextendsChangeNotifier{ThemeMode_themeMode;ThemeController({ThemeModeinitial=ThemeMode.system}):_themeMode=initial;ThemeModegetthemeMode=>_themeMode;boolgetisDark=>_themeMode==ThemeMode.dark;voidsetThemeMode(ThemeModemode){_themeMode=mode;PreferencesService.saveThemeMode(mode.index);notifyListeners();}voidtoggleTheme(){setThemeMode(isDark?ThemeMode.light:ThemeMode.dark);}// 跟随系统voidfollowSystem()=>setThemeMode(ThemeMode.system);}// 在 App 入口ChangeNotifierProvider(create:(_)=>ThemeController(initial:ThemeMode.values[PreferencesService.getThemeMode()],),child:Consumer<ThemeController>(builder:(context,themeController,_)=>MaterialApp(theme:AppTheme.lightTheme,darkTheme:AppTheme.darkTheme,themeMode:themeController.themeMode,home:constHomePage(),),),)

二、自定义颜色与字体系统

2.1 Material 3 颜色系统

// 从种子色生成完整颜色系统finalcolorScheme=ColorScheme.fromSeed(seedColor:constColor(0xFF6750A4),brightness:Brightness.light,);// 颜色角色对应表// primary → 主要操作按钮背景// onPrimary → primary 上的文字/图标// primaryContainer → 次要容器背景// secondary → 次要操作// surface → 卡片、对话框背景// onSurface → surface 上的文字// error → 错误状态// 在 Widget 中使用Widgetbuild(BuildContextcontext){finalcolorScheme=Theme.of(context).colorScheme;returnContainer(color:colorScheme.primaryContainer,child:Text('Hello',style:TextStyle(color:colorScheme.onPrimaryContainer),),);}

2.2 扩展主题颜色(自定义颜色)

// 定义扩展颜色@immutableclassAppColorsextendsThemeExtension<AppColors>{finalColorsuccess;finalColorwarning;finalColorinfo;finalColorgradientStart;finalColorgradientEnd;constAppColors({requiredthis.success,requiredthis.warning,requiredthis.info,requiredthis.gradientStart,requiredthis.gradientEnd,});@overrideAppColorscopyWith({Color?success,Color?warning,Color?info,Color?gradientStart,Color?gradientEnd,}){returnAppColors(success:success??this.success,warning:warning??this.warning,info:info??this.info,gradientStart:gradientStart??this.gradientStart,gradientEnd:gradientEnd??this.gradientEnd,);}@overrideAppColorslerp(AppColors?other,double t){if(other==null)returnthis;returnAppColors(success:Color.lerp(success,other.success,t)!,warning:Color.lerp(warning,other.warning,t)!,info:Color.lerp(info,other.info,t)!,gradientStart:Color.lerp(gradientStart,other.gradientStart,t)!,gradientEnd:Color.lerp(gradientEnd,other.gradientEnd,t)!,);}// 亮色配置staticconstlight=AppColors(success:Color(0xFF4CAF50),warning:Color(0xFFFF9800),info:Color(0xFF2196F3),gradientStart:Color(0xFF6750A4),gradientEnd:Color(0xFF03DAC6),);// 暗色配置staticconstdark=AppColors(success:Color(0xFF81C784),warning:Color(0xFFFFB74D),info:Color(0xFF64B5F6),gradientStart:Color(0xFFD0BCFF),gradientEnd:Color(0xFF6FF7EC),);}// 注册到 ThemeDataThemeDatagetlightTheme=>ThemeData(extensions:const[AppColors.light],// ...)// 在 Widget 中使用finalappColors=Theme.of(context).extension<AppColors>()!;Container(color:appColors.success)

2.3 自定义字体

# pubspec.yamlflutter:fonts:-family:Outfitfonts:-asset:assets/fonts/Outfit-Regular.ttfweight:400-asset:assets/fonts/Outfit-Medium.ttfweight:500-asset:assets/fonts/Outfit-Bold.ttfweight:700
ThemeDatagettheme=>ThemeData(fontFamily:'Outfit',// 全局字体textTheme:constTextTheme(headlineLarge:TextStyle(fontFamily:'Outfit',fontSize:32,fontWeight:FontWeight.w700,),),)

2.4 动态主题色(用户自定义)

classDynamicThemeControllerextendsChangeNotifier{Color_seedColor=constColor(0xFF6750A4);ColorgetseedColor=>_seedColor;ThemeDatagetlightTheme=>ThemeData(useMaterial3:true,colorScheme:ColorScheme.fromSeed(seedColor:_seedColor,brightness:Brightness.light,),);ThemeDatagetdarkTheme=>ThemeData(useMaterial3:true,colorScheme:ColorScheme.fromSeed(seedColor:_seedColor,brightness:Brightness.dark,),);voidupdateSeedColor(Colorcolor){_seedColor=color;notifyListeners();}}

小结

知识点核心要点
ThemeData定义全局视觉风格,lightTheme + darkTheme
ThemeModesystem / light / dark 三种切换模式
ColorScheme.fromSeed从种子色自动生成 Material 3 完整颜色系统
ThemeExtension扩展自定义颜色,支持亮/暗色自动切换
字体配置pubspec.yaml 注册,fontFamily 全局应用

👉 下一节:6.2 国际化(i18n)

http://www.jsqmd.com/news/636530/

相关文章:

  • 3大神奇功能!AutoCAD字体管理插件FontCenter让设计师告别字体烦恼
  • 2026年贵州智慧停车系统与车牌识别解决方案深度横评:五大品牌无人值守停车场道闸与识别相机对比指南 - 精选优质企业推荐榜
  • 不止是救砖:聊聊chroot这个‘系统手术刀’在Jetson开发中的另类玩法
  • 微信小程序的社区防控代办跑腿系统
  • Python 正则表达式:文本清洗与信息提取速通手册
  • Dify部署
  • uni-app怎么做分包 uni-app小程序分包加载配置【优化】
  • 电子电路中的“心脏”:电源诳
  • 2026年建筑智能化新趋势:专业公司如何引领未来? - 小艾信息发布
  • 如何处理无法修改主键列的问题_先删除AUTO_INCREMENT再移除主键的顺序
  • SQL中如何实现特定范围内数据的批量删除_范围分区与分区删除
  • 股市学习心得-实战操作手法-一切都是为了确定性
  • 大模型面试复盘:从0基础到收获4个Offer,我的转行避坑指南!
  • Unity游戏内嵌Coze智能体:从API调用到实时对话的完整实践
  • MiniCPM-V-2_6金融风控应用:票据图像识别+伪造特征检测实战部署
  • 深度学习新手福音:PyTorch通用开发镜像,一键启动你的第一个AI项目
  • 基于改进快速粒子群算法的动态无功优化软件在含分布式电源系统中的应用与性能优化,采用Matlab...
  • CSS渐变背景在Safari渲染断层_优化渐变色彩区间与渲染模式
  • Pixel4刷机翻车自救指南:从源码下载到内核编译,我踩过的那些坑(Ubuntu 18.04 + Android 12)
  • 从规范到代码:RC522驱动Mifare Ultralight Type2 Tag的实战避坑指南(基于PHY6212平台)
  • ComfyUI快速上手:无需代码,可视化节点设计AI绘画流程
  • AIAgent黑盒变透明:5步实现高可信度可解释架构设计(附NASA/医疗级验证标准)
  • 基于vue的消息推送平台[vue]-计算机毕业设计源码+LW文档
  • AD2S1210旋变芯片在伺服控制中的应用:从芯片手册到电机位置反馈的实战解析
  • 学术PPT别再照搬论文了!哈佛教授建议的幻灯片制作心法(附时间分配表)
  • 告别Cityscapes:手把手教你将DDRNet.pytorch项目适配到自己的小数据集(以细胞图像为例)
  • Android开发实战:用Zxing实现前置摄像头扫码的5个常见坑及解决方案
  • 阿里刚开源下一代RAG王炸框架,AI学会自己翻图、看视频、找资料了
  • 不锈钢彩涂板哪个靠谱
  • FLUX.1-dev FP8量化模型:6GB显存就能玩转专业AI图像生成