fish_redux使用详解---看完就会用! (10)

action

enum ItemAction { onChange, clear, } class ItemActionCreator { //状态改变 static Action onChange(int id) { return Action(ItemAction.onChange, payload: id); } //清除改变的状态 static Action clear() { return Action(ItemAction.clear); } }

reducer

Reducer<ItemState> buildReducer() { return asReducer( <Object, Reducer<ItemState>>{ ItemAction.onChange: _onChange, ItemAction.clear: _clear, }, ); } ItemState _onChange(ItemState state, Action action) { if (state.id == action.payload) { return state.clone()..itemStatus = !state.itemStatus; } ///这地方一定要注意,要返回:state;不能返回:state.clone(),否则会造成后续更新失灵 return state; } ///单选模式 ItemState _clear(ItemState state, Action action) { if (state.itemStatus) { return state.clone()..itemStatus = false; } ///这地方一定要注意,要返回:state;不能返回:state.clone(),否则会造成后续更新失灵 return state; }

这个问题实际上解决起来很简单,但是如果一直在 _onChange 方法重置状态,你会发现和你预期的结果一直对不上;完整且详细的效果,可以去看demo里面代码

搞定

呼,终于将列表这块写完,说实话,这个列表的使用确实有点麻烦;实际上,如果大家用心看了的话,麻烦的地方,其实就是在这块:adapter创建及其绑定;只能多写写了,熟能生巧!

列表模块大功告成,以后就能愉快的写列表了!

img

全局模式 效果图

fish_redux_switch

理解了上面的是三个例子,相信大部分页面,对于你来说都不在话下了;现在我们再来看个例子,官方提供的全局主题功能,当然,这不仅仅是全局主题,全局字体样式,字体大小等等,都是可以全局管理,当然了,写app之前要做好规划

开搞 store模块

文件结构

这地方需要新建一个文件夹,新建四个文件:action,reducer,state,store

image-20200812162317741

state

老规矩,先来看看state,我们这里只在抽象类里面定义了一个主题色,这个抽象类是很重要的,需要做全局模式所有子模块的state,都必须实现这个抽象类

abstract class GlobalBaseState{ Color themeColor; } class GlobalState implements GlobalBaseState, Cloneable<GlobalState>{ @override Color themeColor; @override GlobalState clone() { return GlobalState(); } }

action

因为只做切换主题色,这地方只需要定义一个事件即可

enum GlobalAction { changeThemeColor } class GlobalActionCreator{ static Action onChangeThemeColor(){ return const Action(GlobalAction.changeThemeColor); } }

reducer

这里就是处理变色的一些操作,这是咸鱼官方demo里面代码;这说明简单的逻辑,是可以放在reducer里面写的

import 'package:flutter/material.dart' hide Action; Reducer<GlobalState> buildReducer(){ return asReducer( <Object, Reducer<GlobalState>>{ GlobalAction.changeThemeColor: _onChangeThemeColor, }, ); } List<Color> _colors = <Color>[ Colors.green, Colors.red, Colors.black, Colors.blue ]; GlobalState _onChangeThemeColor(GlobalState state, Action action) { final Color next = _colors[((_colors.indexOf(state.themeColor) + 1) % _colors.length)]; return state.clone()..themeColor = next; }

store

切换全局状态的时候,就需要调用这个类了

/// 建立一个AppStore /// 目前它的功能只有切换主题 class GlobalStore{ static Store<GlobalState> _globalStore; static Store<GlobalState> get store => _globalStore ??= createStore<GlobalState>(GlobalState(), buildReducer()); } main改动

这里面将PageRoutes里面的visitor字段使用起来,状态更新操作代码有点多,就单独提出来了;所以main文件里面,增加了:

visitor字段使用

增加_updateState方法

void main() { runApp(createApp()); } Widget createApp() { ///全局状态更新 _updateState() { return (Object pageState, GlobalState appState) { final GlobalBaseState p = pageState; if (pageState is Cloneable) { final Object copy = pageState.clone(); final GlobalBaseState newState = copy; if (p.themeColor != appState.themeColor) { newState.themeColor = appState.themeColor; } /// 返回新的 state 并将数据设置到 ui return newState; } return pageState; }; } final AbstractRoutes routes = PageRoutes( ///全局状态管理:只有特定的范围的Page(State继承了全局状态),才需要建立和 AppStore 的连接关系 visitor: (String path, Page<Object, dynamic> page) { if (page.isTypeof<GlobalBaseState>()) { ///建立AppStore驱动PageStore的单向数据连接: 参数1 AppStore 参数2 当AppStore.state变化时,PageStore.state该如何变化 page.connectExtraStore<GlobalState>(GlobalStore.store, _updateState()); } }, ///定义路由 pages: <String, Page<Object, dynamic>>{ ///导航页面 "GuidePage": GuidePage(), ///计数器模块演示 "CountPage": CountPage(), ///页面传值跳转模块演示 "FirstPage": FirstPage(), "SecondPage": SecondPage(), ///列表模块演示 "ListPage": ListPage(), }, ); return MaterialApp( title: 'FishRedux', home: routes.buildPage("GuidePage", null), //作为默认页面 onGenerateRoute: (RouteSettings settings) { //ios页面切换风格 return CupertinoPageRoute(builder: (BuildContext context) { return routes.buildPage(settings.name, settings.arguments); }); }, ); } 子模块使用

这里就用计数器模块的来举例,因为仅仅只需要改动少量代码,且只涉及state和view,所以其它模块代码也不重复贴出了

state

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxfxz.html