这里主要是使用原生框架做全局的状态管理
我的思路是使用管理类管理色彩配置
widget从管理类获取所需的色彩.实现色彩配置
所有常驻内存的widget向管理类递交方法用于色彩配置发生变化的时候被调用
而随界面出现而生成/消失的widget直接获取配置即可
首先创建一个管理类配置色彩
- 创建一个单例类
class SkinConfig{
factory SkinConfig() =>_getInstance();
static SkinConfig get instance => _getInstance();
static SkinConfig _instance;
SkinConfig._internal() {
// 初始化
}
static SkinConfig _getInstance() {
if (_instance == null) {
_instance = new SkinConfig._internal();
}
return _instance;
}
}
- 创建一个属性作为当前色彩类型的标记
//色彩类型
const String skinStyleDay = 'day';
const String skinStyleNight = 'night';
class SkinConfig{
//配色列表
static List skinStyleList = [
skinStyleDay,
skinStyleNight
];
//配色类型标记 不能为空
static String _skinStyle = skinStyleDay;
...
}
- 添加根据标记返回对应色彩的方法
class SkinConfig{
...
//主色
Color mainColor(){
Color color ;
switch (_skinStyle) {
case skinStyleDay : color = Color(0xFFFFBE00);
break;
case skinStyleNight : color = Color(0xFF333333);
break;
}
return color;
}
//主背景色
Color mainBGColor(){
Color color ;
switch (_skinStyle) {
case skinStyleDay : color = Color(0xFFF8F8F8);
break;
case skinStyleNight : color = Color(0xFF191C29);
break;
}
return color;
}
...
}
这样,只要改变SkinConfig()单例中的 _skinStyle 属性就可以在mainColor(),mainBGColor()方法中得到对应类型的色彩了
添加配置,本地化存储方法
切换类型,我这里因为只牵涉黑白两版的切花所以使用一个轮换方法就可以,但是这里的方案实际是给多种皮肤配置预留的,需要制定类型的话增加指定参数即可.本地保存的方法我使用的是上一篇博客中介绍的在NSUserdefault中保存一个value的方案
- 设置切换,保存的方法
class SkinConfig{
...
//读取已保存的配色
void readDefaultModel(){
HardwareIO.instance.readUserDefault(skinStyleKey, (String value){
if(skinStyleList.contains(value)){
_skinStyle = value;
}else{
_skinStyle = skinStyleDay;
}
});
}
//切换色彩配置
void switchModel(){
//轮换配色
int currentIndex = skinStyleList.indexOf(_skinStyle);
int destIndex = 0;
if(currentIndex < skinStyleList.length - 1){
destIndex = currentIndex + 1;
}
_skinStyle = skinStyleList.elementAt(destIndex);
//保存已选配色类型
HardwareIO.instance.setUserDefault(skinStyleKey, skinStyleList.elementAt(destIndex),(String result){});
}
...
}
- 在初始化的时候读取一次已保存的配色
static SkinConfig _getInstance() {
if (_instance == null) {
_instance = new SkinConfig._internal();
_instance.readDefaultModel();
}
return _instance;
}
这样就完成了色彩配置,存储,获取的完整工具。
通过方法传递在色彩配置发生变动的时候setstate
完成上述色彩管理类的配置之后,在任何一个地方调用获取色彩方法即可获取当前对应的色彩.但是如果色彩发生了变化,而对应的widget没有重新build或者setstate是不会发生变化的.因此我们选择将需要随色彩管理类变动而变动的widget的setstate方法作为变量传递给ColorConfig类,在发生色彩变动时 由ColorConfig进行回调即可.
- 在ColorConfig类中使用List注册需要回调的n方法
class SkinConfig{
···
//色彩变动时候需要被调用的方法
List<Function> changeReceiver = new List();
//注册回调
void regChangeAction(Function function()){
changeReceiver.add(function);
print(changeReceiver.toString());
}
//反注册回调
void unRegChangeAction(Function function()){
changeReceiver.remove(function);
print(changeReceiver.toString());
}
//调用回调
void changeSkinCallBack(){
for(int i = 0 ; i < changeReceiver.length;i++){
Function function = changeReceiver[i];
function();
}
}
···
}
- 在色彩发生变动的位置调用回调
//轮换配色
void switchModel(){
···
changeSkinCallBack();
}
//读取已保存的配色
void readDefaultModel(){
HardwareIO.instance.readUserDefault(skinStyleKey, (String value){
···
changeSkinCallBack();
});
}
这样整个色彩配置管理类就完成了
如何调用
获取对应色彩 ,只需要使用ColorConfig()....color()即可
色彩发生变化时对于所有在内存中驻留,需要被主动通知到的widget则需要
- 包装setstate方法
- 将该方法注册到ColorConfig的回调列表中
- 注意在dispose中进行反注册
class _SelfPageState extends State<SelfPage>{
Function changeSkinFunction ;
@override
void initState() {
// TODO: implement initState
//包装setstate方法
changeSkinFunction = (){
setState(() {
});
};
//注册该回调
SkinConfig().regChangeAction(
changeSkinFunction
);
super.initState();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text('市场'),
//配置色彩
backgroundColor: SkinConfig().mainColor(),
),
);
}
@override
void dispose() {
// TODO: implement dispose
//反注册这个类的回调
SkinConfig().unRegChangeAction(changeSkinFunction);
super.dispose();
}
}