1、网络请求;
2、切换主题,全局Store的使用;
3、broadcast的使用;
主题切换和全局store的使用:
这里在个人中心加了一个简单的切换夜间模式的功能,需要一个全局的Store这里直接是使用fish-redux的example中的global_store包里的东西,只是把themeColor换成自己定义的主题,至于初始化咱就在创建的地方初始化一下数据,如下代码:
class GlobalStore {
static Store _globalStore;
static Store get store {
return _globalStore ??= createStore(
GlobalState()..appTheme = AppTheme.getInstance(false), buildReducer());
}
}
入口页也需要改造成fish-redux的方式,直接新建一个page就是,这个新建方式在之前的博客有提到,是他们团队提供的插件,这里就不在多做介绍了,如下代码:
Widget buildView(MainState state, Dispatch dispatch, ViewService viewService) {
return MaterialApp(
title: 'Flutter Demo',
theme: state.appTheme.dark ? darkTheme : lightTheme,
home: routes.buildPage('home', null),
routes: appRoutes,
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute
这里的darkTheme 和 lightTheme都在AppTheme中。
还需要在一个地方处理一下这个store,如下所示:
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'constant/theme.dart';
import 'global_store/state.dart';
import 'global_store/store.dart';
import 'home/index/page.dart';
import 'home/index/page/page.dart';
import 'home/mine/page.dart';
import 'home/page.dart';
import 'home/smart/page.dart';
import 'page.dart';
import 'radio/page.dart';
Map appRoutes = {
'/home': (BuildContext context) => routes.buildPage("home", null),
'/main': (BuildContext context) => routes.buildPage("main", null),
'/radioDetail': (BuildContext context) =>
routes.buildPage("radioDetail", null),
};
var routes = new PageRoutes(
pages: >{
'home': HomePage(),
'main': MainPage(),
'index': IndexPage(),
'smart': SmartPage(),
'mine': MinePage(),
'indexTab': TabPage(),
'radioDetail': RadioDetailPage(), //电台详情页
},
visitor: (String path, Page
这里其实也是在fish-redux上复制的,其实就是遍历所有page判断theme是否改变,改变了就重新clone赋值。
然后在你要用到的地方的State的实现GlobalBaseState,这个抽象类,如下所示:
abstract class GlobalBaseState {
AppTheme get appTheme;
set appTheme(AppTheme appTheme);
}
这个AppTheme类是我自己定义的,其实就是我们主题切换时对应的字体颜色等样式,这里就不贴出来了,下面有代码地址,大家可以自行clone跑一下。
这里列出来一个我实现这个GlobalBaseState的类,个人中心的State类,如下所示:
class MineState implements GlobalBaseState, Cloneable {
bool darkOn;
bool gridOn;
@override
MineState clone() {
return MineState()
..appTheme = appTheme
..darkOn = darkOn
..gridOn = gridOn;
}
@override
AppTheme appTheme;
}
MineState initState(Map args) {
return MineState()
..gridOn = false
..darkOn = Constants.dark;
}
其实就是实现一下,然后在clone加上这个apptheme就行了,
调用切换主题如下代码:
Widget buildView(MineState state, Dispatch dispatch, ViewService viewService) {
return ListView(
children: [
ListTile(
leading: Icon(Icons.brightness_2),
title: Text('夜间模式', style: state.appTheme.titleStyle),
trailing: Switch(
value: state.darkOn,
onChanged: (value) {
print("onchange---------$value");
GlobalStore.store
.dispatch(GlobalActionCreator.onchangeThemeColor(value));
dispatch(MineActionCreator.changeThemeAction(value));
dispatch(MineActionCreator.changeThemeEffect(value));
}),
),
ListTile(
leading: Icon(Icons.grid_on),
title: Text('GridView显示', style: state.appTheme.titleStyle),
trailing: Switch(
value: state.gridOn,
onChanged: (value) {
dispatch(MineActionCreator.changeGridAction(value));
}),
)
],
);
}
改变主题时候有个坑,不知道是不是我的方式不对还是咋的,理论上调用 GlobalStore.store .dispatch(GlobalActionCreator.onchangeThemeColor(value));就可以,但是我这里主题是切换了,但是我这列表每个Item文字颜色等都没改变,所以改成另外一种方式了。
这里我们可以看到我直接在这里还调用了其他方法,这里起作用的是这dispatch(MineActionCreator.changeThemeEffect(value));
我把这个action发送的 个人中心的effect里,如下所示:
Effect buildEffect() {
return combineEffects(
就是这个方法__changeThemeEffect接收到view中action然后我在这里发一个广播,我只要在item中注册这个广播就可以收到改变主题的action了,这里本来打算直接注册在reducer中的,但是发现不起作用所以最后注册到effect中才能接收到,如下代码:
Effect buildEffect() {
return combineEffects(
因此我这里还需要发一次action才能改变每个item的颜色,感觉比较麻烦,不知道大家还有没有更好的办法实现,如果有的话希望大神提供一下思路,小弟不胜感激。
流程差不多就这样了,大家可以直接clone代码,跑一下就可以看到效果了。后续还会介绍我在用flutter开发app过程种,Android和苹果遇到的问题,以及两个平台上插件的问题
传送门:demo