6.1 主题与暗色模式

张开发
2026/4/13 23:20:42 15 分钟阅读

分享文章

6.1 主题与暗色模式
Flutter 的主题系统ThemeData提供了统一的视觉风格管理通过 Material 3 的颜色系统和深色模式支持可以轻松构建专业的视觉体系。一、ThemeData 动态切换1.1 定义双主题classAppTheme{// 亮色主题staticThemeDatagetlightThemeThemeData(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,),);// 暗色主题staticThemeDatagetdarkThemeThemeData(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){finalcolorbrightnessBrightness.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({ThemeModeinitialThemeMode.system}):_themeModeinitial;ThemeModegetthemeMode_themeMode;boolgetisDark_themeModeThemeMode.dark;voidsetThemeMode(ThemeModemode){_themeModemode;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:ConsumerThemeController(builder:(context,themeController,_)MaterialApp(theme:AppTheme.lightTheme,darkTheme:AppTheme.darkTheme,themeMode:themeController.themeMode,home:constHomePage(),),),)二、自定义颜色与字体系统2.1 Material 3 颜色系统// 从种子色生成完整颜色系统finalcolorSchemeColorScheme.fromSeed(seedColor:constColor(0xFF6750A4),brightness:Brightness.light,);// 颜色角色对应表// primary → 主要操作按钮背景// onPrimary → primary 上的文字/图标// primaryContainer → 次要容器背景// secondary → 次要操作// surface → 卡片、对话框背景// onSurface → surface 上的文字// error → 错误状态// 在 Widget 中使用Widgetbuild(BuildContextcontext){finalcolorSchemeTheme.of(context).colorScheme;returnContainer(color:colorScheme.primaryContainer,child:Text(Hello,style:TextStyle(color:colorScheme.onPrimaryContainer),),);}2.2 扩展主题颜色自定义颜色// 定义扩展颜色immutableclassAppColorsextendsThemeExtensionAppColors{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(othernull)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)!,);}// 亮色配置staticconstlightAppColors(success:Color(0xFF4CAF50),warning:Color(0xFFFF9800),info:Color(0xFF2196F3),gradientStart:Color(0xFF6750A4),gradientEnd:Color(0xFF03DAC6),);// 暗色配置staticconstdarkAppColors(success:Color(0xFF81C784),warning:Color(0xFFFFB74D),info:Color(0xFF64B5F6),gradientStart:Color(0xFFD0BCFF),gradientEnd:Color(0xFF6FF7EC),);}// 注册到 ThemeDataThemeDatagetlightThemeThemeData(extensions:const[AppColors.light],// ...)// 在 Widget 中使用finalappColorsTheme.of(context).extensionAppColors()!;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:700ThemeDatagetthemeThemeData(fontFamily:Outfit,// 全局字体textTheme:constTextTheme(headlineLarge:TextStyle(fontFamily:Outfit,fontSize:32,fontWeight:FontWeight.w700,),),)2.4 动态主题色用户自定义classDynamicThemeControllerextendsChangeNotifier{Color_seedColorconstColor(0xFF6750A4);ColorgetseedColor_seedColor;ThemeDatagetlightThemeThemeData(useMaterial3:true,colorScheme:ColorScheme.fromSeed(seedColor:_seedColor,brightness:Brightness.light,),);ThemeDatagetdarkThemeThemeData(useMaterial3:true,colorScheme:ColorScheme.fromSeed(seedColor:_seedColor,brightness:Brightness.dark,),);voidupdateSeedColor(Colorcolor){_seedColorcolor;notifyListeners();}}小结知识点核心要点ThemeData定义全局视觉风格lightTheme darkThemeThemeModesystem / light / dark 三种切换模式ColorScheme.fromSeed从种子色自动生成 Material 3 完整颜色系统ThemeExtension扩展自定义颜色支持亮/暗色自动切换字体配置pubspec.yaml 注册fontFamily 全局应用 下一节6.2 国际化i18n

更多文章