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();
@override
Widget build(BuildContext context) {
//定义不同的ThemeData
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)],
);
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);
@override
ThemeExtension<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;
}
@override
ThemeExtension<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页面启动!");
}
@override
State<StatefulWidget> createState() => AState();
}
class AState extends State<A>{
@override
Widget 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();
@override
Widget 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);
@override
ThemeExtension<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;
}
@override
ThemeExtension<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页面启动!");
}
@override
State<StatefulWidget> createState() => AState();
}
class AState extends State<A>{
@override
Widget 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页面启动!");
}
@override
State<StatefulWidget> createState() => BState();
}
class BState extends State<B>{
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"),
),
);
}
}
class C extends StatefulWidget{
@override
State<StatefulWidget> createState() => CState();
}
class CState extends State<C>{
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("CCCCCCCCCCCCCCCCCCCCCCCCC"),
),
);
}
}
class MyPageTransitionsBuilder extends PageTransitionsBuilder {
@override
Widget 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 搞定!