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

可以看到Checkbox的内部点击操作,我们传递了一个id参数,注意这个id参数是必须的,在更新item的时候来做区分用的

Widget buildView(ItemState state, Dispatch dispatch, ViewService viewService) { return Container( child: InkWell( onTap: () {}, child: ListTile( title: Text(state.title), trailing: Checkbox( value: state.itemStatus, ///Checkbox的点击操作:状态变更 onChanged: (value) => dispatch(ItemActionCreator.onChange(state.id)), ), ), ), ); }

action

一个状态改变的事件

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

reducer

_onChange会回调所有ItemState,所以这地方必须用id或其它唯一标识去界定,我们所操作的item具体是哪一个

_onChange方法,未操作的item返回的时候要注意,需要返回:state原对象,标明该state对象未变动,其item不需要刷新;不能返回state.clone(),这样返回的就是个全新的state对象,每个item都会刷新,还会造成一个很奇怪的bug,会造成后续点击item操作失灵

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

注意:如果使用多样式,items的列表泛型不要写成ItemState,写成Object就行了;在下面代码,我们可以看到,实现的getItemData()方法返回的类型是Object,所以Items的列表泛型写成Object,是完全可以的。

我们定义数据源的时候把泛型写成Object是完全可以的,但是初始化数据的时候一定要注意,写成对应adapter类型里面的state

假设一种情况,在index是奇数时展示:OneComponent;在index是奇数时展示:TwoComponent;

getItemType:这个重写方法里面,在index为奇偶数时分别返回:OneComponent和TwoComponent的标识

数据赋值时也一定要在index为奇偶数时赋值泛型分别为:OneState和TwoState

也可以这样优化去做,在getItemType里面判断当前泛型是什么数据类型,然后再返回对应的XxxxComponent的标识

数据源的数据类型必须和getItemType返回的XxxxComponent的标识相对应,如果数据源搞成Object类型,映射到对应位置的item数据时,会报类型不适配的错误

下述代码可做思路参考

class ListState extends MutableSource implements Cloneable<PackageCardState> { List<Object> items; @override ListState clone() { return PackageCardState()..items = items; } @override Object getItemData(int index) => items[index]; @override String getItemType(int index) { if(items[index] is OneState) { return PackageCardAdapter.itemStyleOne; }else{ return PackageCardAdapter.itemStyleTwo; } } @override int get itemCount => items.length; @override void setItemData(int index, Object data) => items[index] = data; } 列表存在的问题+解决方案 列表多item刷新问题

这里搞定了单item刷新场景,还存在一种多item刷新的场景

说明下,列表item是没办法一次刷新多个item的,只能一次刷新一个item(一个clone对应着一次刷新),一个事件对应着刷新一个item;这边是打印多个日志分析出来了

解决:解决办法是,多个事件去处理刷新操作

举例:假设一种场景,对于上面的item只能单选,一个item项被选中,其它item状态被重置到未选状态,具体效果看下方效果图

效果图

单选模式

这种效果的实现非常简单,但是如果思路不对,会掉进坑里出不来

还原被选的状态,不能在同一个事件里写,需要新写一个清除事件

下述代码为整体流程

view

Widget buildView(ItemState state, Dispatch dispatch, ViewService viewService) { return InkWell( onTap: () {}, child: ListTile( title: Text(state.title), trailing: Checkbox( value: state.itemStatus, ///CheckBox的点击操作:状态变更 onChanged: (value) { //单选模式,清除选中的item,以便做单选 dispatch(ItemActionCreator.clear()); //刷新选中item dispatch(ItemActionCreator.onChange(state.id)); } ), ), ); }

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

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