ThemeData
factory ThemeData({bool? applyElevationOverlayColor, //material2的darkTheme下 增加一个半透明遮罩 来凸显阴影效果 material3下无效 貌似没啥用NoDefaultCupertinoThemeData? cupertinoOverrideTheme, //ios组件样式 Iterable<ThemeExtension<dynamic>>? extensions, //自定义颜色 可用于统一颜色处理InputDecorationTheme? inputDecorationTheme, //TextField的主题样式MaterialTapTargetSize? materialTapTargetSize, //配置可点击的weight 的点击目标和布局大小PageTransitionsTheme? pageTransitionsTheme, //定义页面过度动画...
}
extensions
- Iterable<ThemeExtension>? extensions
- 自定义颜色 可用于统一颜色处理 (定一个常量类不是更简单么 em…)
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';main(){runApp(const MyApp());
}class MyApp extends StatelessWidget{const MyApp();@overrideWidget build(BuildContext context) {
//定义不同的ThemeDataThemeData themeRed = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 0)],);ThemeData themeGreen = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 1)],);ThemeData themeBlue = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 2)],);return MaterialApp(theme: themeBlue, //使用ThemeData 显示不同的颜色home: A(),);}void changeTheme(){}
}class ThemeColors extends ThemeExtension<ThemeColors>{static String main_color = "main_color";static String text_color = "text_color";static String text_background = "text_background";var themeType = 0;var themeRed = {main_color:Colors.red,text_color:const Color(0xFFD26161),text_background:const Color(0xFFEAE4E4),};var themeGreen = {main_color:Colors.green,text_color:const Color(0xFF6EDC9A),text_background:const Color(0xFFEAE4E4),};var themeBlue = {main_color:Colors.blue,text_color:const Color(0xFF6F83E7),text_background:const Color(0xFFEAE4E4),};ThemeColors({this.themeType = 0});ThemeColors.themeRed(this.themeRed);ThemeColors.themeGreen(this.themeGreen);ThemeColors.themeBlue(this.themeBlue);@overrideThemeExtension<ThemeColors> copyWith() {var result = null;switch(this.themeType){case 0:result = ThemeColors.themeRed(themeRed);break;case 1:result = ThemeColors.themeGreen(themeGreen);break;case 2:result = ThemeColors.themeBlue(themeBlue);break;}return result;}@overrideThemeExtension<ThemeColors> lerp(covariant ThemeExtension<ThemeColors>? other, double t) {if(other !is ThemeColors){return this;}var result = null;switch(this.themeType){case 0:result = ThemeColors.themeRed(themeRed);break;case 1:result = ThemeColors.themeGreen(themeGreen);break;case 2:result = ThemeColors.themeBlue(themeBlue);break;}return result;}Color getColor(String colorName){var resultMap = null;switch(this.themeType){case 0:resultMap = themeRed;break;case 1:resultMap = themeGreen;break;case 2:resultMap = themeBlue;break;}return resultMap[colorName];}}class A extends StatefulWidget{A(){print("A页面启动!");}@overrideState<StatefulWidget> createState() => AState();
}class AState extends State<A>{@overrideWidget build(BuildContext context) {ThemeColors themeColors = Theme.of(context).extension<ThemeColors>()??ThemeColors(themeType: 0);return Scaffold(backgroundColor: themeColors.getColor(ThemeColors.main_color), //背景色使用主题的颜色);}
}
结果
theme: themeRed, //红色
theme: themeGreen, //绿色
theme: themeBlue, //蓝色
inputDecorationTheme
- 输入框的样式 定义输入框各种显示样式及交互样式
ThemeData themeBlue = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 2)],inputDecorationTheme: InputDecorationTheme(labelStyle: TextStyle(color: Colors.black), //黑字hintStyle: TextStyle(color: Colors.grey), //hint字体 灰色border: UnderlineInputBorder(), //底部划线边框focusedBorder: UnderlineInputBorder(),));
属性
const InputDecorationTheme({this.labelStyle,this.floatingLabelStyle,this.helperStyle,this.helperMaxLines,this.hintStyle,this.errorStyle,this.errorMaxLines,this.floatingLabelBehavior = FloatingLabelBehavior.auto,this.floatingLabelAlignment = FloatingLabelAlignment.start,this.isDense = false,this.contentPadding,this.isCollapsed = false,this.iconColor,this.prefixStyle,this.prefixIconColor,this.suffixStyle,this.suffixIconColor,this.counterStyle,this.filled = false,this.fillColor,this.activeIndicatorBorder,this.outlineBorder,this.focusColor,this.hoverColor,this.errorBorder,this.focusedBorder,this.focusedErrorBorder,this.disabledBorder,this.enabledBorder,this.border,this.alignLabelWithHint = false,this.constraints,});
materialTapTargetSize
- 组件最小点击区域
- 取值 如下
enum MaterialTapTargetSize {/// Expands the minimum tap target size to 48px by 48px. 将最小点击目标大小扩展为 48px x 48px。////// This is the default value of [ThemeData.materialTapTargetSize] and the/// recommended size to conform to Android accessibility scanner/// recommendations.padded,/// Shrinks the tap target size to the minimum provided by the Material 将点击目标尺寸缩小到Material 规范提供的最小值。/// specification.shrinkWrap,
}
pageTransitionsTheme
- 页面切换动画
- 切换动画支持 android ios macos
默认页面切换动画
修改后的切换动画 从下往上顶出动画
pageTransitionsTheme:PageTransitionsTheme(builders: <TargetPlatform, PageTransitionsBuilder>{TargetPlatform.android:OpenUpwardsPageTransitionsBuilder()}),
自定义页面切换动画
class MyPageTransitionsBuilder extends PageTransitionsBuilder {@override![请添加图片描述](https://img-blog.csdnimg.cn/direct/8874fd6cec764fa4a1b042b4d46bb67d.gif)Widget buildTransitions<T>(PageRoute<T>? route,BuildContext? context,Animation<double> animation, //显示页面执行的动画Animation<double> secondaryAnimation, //隐藏页面执行的动画Widget? child,) {return ScaleTransition( //缩放动画 scale: animation,child: RotationTransition( //旋转动画turns: animation,child: child,),);}
}
结果:B页面旋转放大显示
若 return改为如下
return ScaleTransition( //B页面放大scale: animation,child: RotationTransition( //A页面旋转turns: secondaryAnimation,child: child,),);
效果如下
其它类型动画 改变return即可 或可仿照系统默认切换动画类改造自己想要的动画
return SizeTransition(sizeFactor: animation,child: SizeTransition(sizeFactor: animation,child: child,),);
全部代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';main(){runApp(const MyApp());
}class MyApp extends StatelessWidget{const MyApp();@overrideWidget build(BuildContext context) {ThemeData themeRed = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 0)],);ThemeData themeGreen = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 1)],);ThemeData themeBlue = ThemeData.light().copyWith(extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 2)],inputDecorationTheme: InputDecorationTheme(labelStyle: TextStyle(color: Colors.black),hintStyle: TextStyle(color: Colors.grey),border: UnderlineInputBorder(),focusedBorder: UnderlineInputBorder(),),materialTapTargetSize:MaterialTapTargetSize.shrinkWrap,pageTransitionsTheme:PageTransitionsTheme(builders: <TargetPlatform, PageTransitionsBuilder>{TargetPlatform.android:MyPageTransitionsBuilder()}),);return MaterialApp(theme: themeBlue,home: A(),routes: {"/A": (context) => A(),"/B": (context) => B(),"/C": (context) => C(),},);}void changeTheme(){}
}class ThemeColors extends ThemeExtension<ThemeColors>{static String main_color = "main_color";static String text_color = "text_color";static String text_background = "text_background";var themeType = 0;var themeRed = {main_color:Colors.red,text_color:const Color(0xFFD26161),text_background:const Color(0xFFEAE4E4),};var themeGreen = {main_color:Colors.green,text_color:const Color(0xFF6EDC9A),text_background:const Color(0xFFEAE4E4),};var themeBlue = {main_color:Colors.blue,text_color:const Color(0xFF6F83E7),text_background:const Color(0xFFEAE4E4),};ThemeColors({this.themeType = 0});ThemeColors.themeRed(this.themeRed);ThemeColors.themeGreen(this.themeGreen);ThemeColors.themeBlue(this.themeBlue);@overrideThemeExtension<ThemeColors> copyWith() {var result = null;switch(this.themeType){case 0:result = ThemeColors.themeRed(themeRed);break;case 1:result = ThemeColors.themeGreen(themeGreen);break;case 2:result = ThemeColors.themeBlue(themeBlue);break;}return result;}@overrideThemeExtension<ThemeColors> lerp(covariant ThemeExtension<ThemeColors>? other, double t) {if(other !is ThemeColors){return this;}var result = null;switch(this.themeType){case 0:result = ThemeColors.themeRed(themeRed);break;case 1:result = ThemeColors.themeGreen(themeGreen);break;case 2:result = ThemeColors.themeBlue(themeBlue);break;}return result;}Color getColor(String colorName){var resultMap = null;switch(this.themeType){case 0:resultMap = themeRed;break;case 1:resultMap = themeGreen;break;case 2:resultMap = themeBlue;break;}return resultMap[colorName];}}class A extends StatefulWidget{A(){print("A页面启动!");}@overrideState<StatefulWidget> createState() => AState();
}class AState extends State<A>{@overrideWidget build(BuildContext context) {ThemeColors themeColors = Theme.of(context).extension<ThemeColors>()??ThemeColors(themeType: 0);return Scaffold(backgroundColor: themeColors.getColor(ThemeColors.main_color),body: Container(child: Column(children: [// TextField(// decoration: InputDecoration(// hintText: "请输入内容"// ),// ),TextButton(onPressed: (){Navigator.pushNamed(context, '/B');}, child: Text("B"),style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.green),padding: MaterialStateProperty.all(EdgeInsets.all(100))),),TextButton(onPressed: (){Navigator.pushNamed(context, '/C');}, child: Text("C"),style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red),padding: MaterialStateProperty.all(EdgeInsets.all(100)),),),],),),);}
}class B extends StatefulWidget{B(){print("B页面启动!");}@overrideState<StatefulWidget> createState() => BState();
}class BState extends State<B>{@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Text("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"),),);}
}class C extends StatefulWidget{@overrideState<StatefulWidget> createState() => CState();
}class CState extends State<C>{@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Text("CCCCCCCCCCCCCCCCCCCCCCCCC"),),);}
}class MyPageTransitionsBuilder extends PageTransitionsBuilder {@overrideWidget buildTransitions<T>(PageRoute<T>? route,BuildContext? context,Animation<double> animation,Animation<double> secondaryAnimation,Widget? child,) {// return ScaleTransition(// scale: animation,// child: RotationTransition(// turns: secondaryAnimation,// child: child,// ),// );return SizeTransition(sizeFactor: animation,child: SizeTransition(sizeFactor: animation,child: child,),);}
}
其他分享
- 学习过程中最大的方式就是查看源码
比如pageTransitionsTheme 此属性传什么值 怎么传
Android Studio 使用 Ctrl+左键
Ctrl+左键 点击
需要一个 builders参数
并且有个 defalutBuilder
基本上可以知道怎么使用
再加上 百度/google 搞定!