主题设置
效果如下图
实现方法
核心:通过跨组件状态共享provider,更改MaterialAPP的theme属性。
Flutter 官方鼓励我们在写 Flutter 应用的时候直接从 MaterialApp 开始,原因是 MaterialApp
为我们集成好了很多 Material Design 所必须的控件,如AnimatedThemen、GridPager 等,另外还通过MaterialApp 配置了全局路由,方便进行页面的切换
provider基本用法;1、新建状态管理类。 2、顶层注册状态管理类。3、状态组件绑定 。4、状态变更。
1、第一步
新建一个themeModel.dart数据model类(即我们要共享的状态)
import 'package:flutter/material.dart';
/*1.创建theme数据Model
这里的 Model 实际上就是我们的状态,它不仅储存了我们的数据模型,而且还包含了更改数据的方法,并暴露出它想要暴露出的数据
*/
class ThemeModel with ChangeNotifier {
String _theme = 'blue';
String get value => _theme;
void setTheme(color) async
{
_theme = color;
print(_theme);
notifyListeners(); //通知依赖的Widget更新
}
}
2、第二步
在main.dart文件main方法里注册顶层共享数据。注意导入provider包和新建的themeModel类
void main() {
//2、注册顶层共享数据
return runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context)=>ThemeModel()),//此是主题状态注册
],
child: MyApp(),
)
);
}
MultiProvider用来注册你需要共享的状态,。
3、第三步
新建一个theme类,我们改变主题其产生对应的设置。当然也可以不这样改变整个theme,而只对theme属性下的primaryColor进行改变
import 'package:flutter/material.dart';
Map materialColor = { // 主副颜色
'purple': {
"primaryColor": 0xFF7B1FA2,
"primaryColorLight": 0xFF9C27B0,
},
'pink': {
"primaryColor": 0xFFc2185b,
"primaryColorLight": 0xFFd81b60,
},
'deeppink': {
"primaryColor": 0xFFf50057,
"primaryColorLight": 0xFFe91e63,
},
'blue': {
"primaryColor": 0xFF1976D2,
"primaryColorLight": 0xFF2196F3,
},
};
class AppTheme {
static Map mainColor = materialColor['blue']; // 默认颜色
static getThemeData(String theme) { // 获取theme方法: getThemeData();
mainColor = materialColor[theme]; // 设置主题颜色
ThemeData themData = ThemeData(
// scaffoldBackgroundColor: Colors.red, // 页面的背景颜色
primaryColor: Color(mainColor["primaryColor"]), // 主颜色
primaryColorLight: Color(mainColor["primaryColorLight"]),
// 按钮颜色
buttonTheme: ButtonThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
textTheme: ButtonTextTheme.normal,
buttonColor: Color(mainColor["primaryColor"]),
),
// 小部件的前景色(旋钮,文本,过度滚动边缘效果等)。
accentColor: Color(mainColor["primaryColor"]),
// appbar样式
appBarTheme: AppBarTheme(
iconTheme: IconThemeData(color: Colors.white),
textTheme: TextTheme(
title: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
),
// 图标样式
iconTheme: IconThemeData(
color: Color(mainColor["primaryColor"]),
),
// 用于自定义对话框形状的主题。
dialogTheme: DialogTheme(
backgroundColor: Colors.white,
titleTextStyle: TextStyle(
fontSize: 18.0,
color: Colors.black87,
),
),
);
return themData;
}
}
themeData介绍:
4、第四步
在main.dart文件中的MyApp类中将主题状态与theme组件绑定
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//3、状态组件绑定,将主题状态与组件绑定
return Consumer<ThemeModel>( //主题设置1:状态获取方式
builder: (context,themeModel,child)
{
return MaterialApp(
theme: AppTheme.getThemeData(themeModel.value), //主题设置2
title: 'Yshow',
initialRoute: welcomeRoute,//欢迎页
routes: routes //注册路由
);
},
);
}
}
关键是主题设置标注的两处,Consumer是获取你注册的状态的一种方式
Consumer 使用了 Builder 模式,收到更新通知就会通过 builder 重新构建。
Consumer<T>
代表了它要获取哪一个祖先中的 Model。Consumer 的 builder 实际上就是一个 Function,它接收三个参数
(BuildContext context, T model, Widget child)
。
- context: context 就是 build 方法传进来的 BuildContext 在这里就不细说了,如果有兴趣可以看我之前这篇文章 Flutter | 深入理解BuildContext。
- T:T也很简单,就是获取到的最近一个祖先节点中的数据模型。
- child:它用来构建那些与 Model 无关的部分,在多次运行 builder 中,child 不会进行重建。
Consumer2<A,B>
使用方式基本上和Consumer<T>
一致,只不过范型改为了两个,并且 builder 方法也变成了Function(BuildContext context, A value, B value2, Widget child)
。我勒个去...假如我要获得 100 个 Model,那岂不是得搞个 Consumer100 (???黑人问号.jpg)
然而并没有 😏。
从源码里面可以看到,作者只为我们搞到了
Consumer6
。emmmmm.....还要要求更多就只有自力更生喽。
作者:Vadaski
链接:https://juejin.im/post/6844903864852807694
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。作者:Vadaski
链接:https://juejin.im/post/6844903864852807694
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
5、第五步
在你需要设置主题的地方调用另一种获取状态的方式Provider.of(context)调用内部设置方法改变主题
if (i != null) {
if(i==1)
{
Provider.of<ThemeModel>(context,listen: false).setTheme('blue');
}
else if(i==2)
{
Provider.of<ThemeModel>(context,listen:false).setTheme('purple');
}
else if(i==3)
{
Provider.of<ThemeModel>(context,listen: false).setTheme('pink');
}
else if(i==4)
{
Provider.of<ThemeModel>(context,listen:false).setTheme('deeppink');
}
}
源码地址
https://github.com/Yimi81/Flutter-ThemeAndLang