美文网首页
fish-redux之 adapter基础使用

fish-redux之 adapter基础使用

作者: 灯红酒绿映不出的落寞 | 来源:发表于2019-08-02 14:12 被阅读0次

    官方文档介绍

    adapter为fish_redux团队对listView的优化封装,适用于长列表渲染,其中实现方式有以下三种
    • DynamicFlowAdapter 接受数组类型的数据驱动
    • StaticFlowAdapter 接受map类型的数据驱动
    • CustomAdapter 自定义 adapter
    1. DynamicFlowAdapter
    class ListGroupAdapter extends DynamicFlowAdapter<AdapterTestState> {
      ListGroupAdapter()
          : super(pool: <String, Component<Object>>{
              'header': ListHeaderComponent(),
              'cell': ListCellComponent(),
              'footer': ListFooterComponent()
            }, connector: ListGroupConnector());
    }
    
    class ListGroupConnector extends ConnOp<AdapterTestState, List<ItemBean>> {
      @override
      List<ItemBean> get(AdapterTestState state) {
        List<ItemBean> items = [];
        if (state.cellModels.length == 0) {
          return items;
        }
        items.add(ItemBean('header', state.headerModel));
        for (var cellModel in state.cellModels) {
          items.add(ItemBean('cell', cellModel));
        }
        items.add(ItemBean('footer', state.footerStr));
        return items;
      }
    }
    
    • 主要由两部分组成,分别是adapter和connector(连接器)
    • adapter-pool 声明依赖组件,内部通过唯一标识符进行标记,注意一点是connector中的唯一标识符,他们需要一样
    • adapter-connector 数据源操作,可以看到ListGroupConnector为数据源处理,唯一标识符必须和adapter-pool中的一致,数据源封装是通过fish_redux开出的ItemBean
    1. StaticFlowAdapter
    
    class SomeStaticAdapter extends StaticFlowAdapter<PageState> {
      SomeStaticAdapter()
        : super(
          slots: [
            SomeComponent().asDependent(SomeComponenConnectt()),
            TaskAdapter().asDependent(TaskAdapterConnect()),
          ],
        );
    
    
    • StaticFlowAdapter接收 map 类型的数据
    • StaticFlowAdapter 没有 pool 属性,但是有 slots,其他的属性与 DynamicFlowAdapter 相同。
    • slots 接受一个数组,里面每一个元素都是与 connect 连接好的 component 或 adapter。
    1. CustomFlowAdapter
    
    class CommentAdapter extends Adapter<PageState> {
        CommentAdapter()
            : super(
                adapter: buildCommentAdapter,
            );
    }
     
    ListAdapter buildCommentAdapter(PageState state, Dispatch dispatch, ViewService service) {
        final List builders = Collections.compact([
            _buildCommentHeader(state, dispatch, service),
        ]);
     
        if (state.commentList.length > 0) {
          builders.addAll(_buildCommentList(state, dispatch, service));
        } else {
          builders.addAll(_buildEmpty(state, dispatch, service));
        }
     
        return ListAdapter(
          (BuildContext buildContext, int index) => builders[index](buildContext, index),
          builders.length,
        );
    
    
    • 上面示例是一个 CustomFlowAdapter,其 adapter 是一个方法 buildCommentAdapter,这个方法返回了一个 ListAdapter。
    • buildCommentAdapter 里根据数据生成一个视图列表。
    • 例如示例中如果 commentList.length > 0 就在 ListAdapter 中加入一个 评论列表,如果没有评论就加入一个空视图的 widget。
    本例通过DynamicFlowAdapter进行叙述,先看UI界面
    Untitled4.gif

    界面组成:ListView构建界面,分为三部分,

    • 头部
    • 中间单元格数组
    • 尾部
    目录结构如下图
    目录.png

    1.main-page

    • 代码示例
    class AdapterTestPage extends Page<AdapterTestState, Map<String, dynamic>> {
      AdapterTestPage()
          : super(
              initState: initState,
              effect: buildEffect(),
              reducer: buildReducer(),
              view: buildView,
              dependencies: Dependencies<AdapterTestState>(
                  adapter: NoneConn<AdapterTestState>() + ListGroupAdapter(),
                  slots: <String, Dependent<AdapterTestState>>{}),
              middleware: <Middleware<AdapterTestState>>[],
            );
    }
    
    
    • adapter和page建立关联,主要通过dependencies下的adapter进行关联,fish_redux下的对应api如下
      /// Use [adapter: NoneConn<T>() + Adapter<T>()] instead of [adapter: Adapter<T>()],
      /// Which is better reusability and consistency.
      Dependencies({
        this.slots,
        this.adapter,
      }) : assert(adapter == null || adapter.isAdapter(),
                'The dependent must contains adapter.');
    
    

    2.view

    • view界面,主要通过viewService下的buildAdapter(),拿到page页的adapter,然后创建对应UI
    • 这里的viewService我们可以看下api信息
    /// Seen in view-part or adapter-part
    abstract class ViewService implements ExtraData {
      /// The way to build adapter which is configured in Dependencies.list
      ListAdapter buildAdapter();
    
      /// The way to build slot component which is configured in Dependencies.slots
      Widget buildComponent(String name);
    
      /// Get BuildContext from the host-widget
      BuildContext get context;
    
      /// Broadcast action(the intent) in app (inter-pages)
      void broadcast(Action action);
    
      /// Broadcast in all component receivers;
      void broadcastEffect(Action action, {bool excluded});
    }
    
    
    • 对应UI
    • 代码示例
    Widget buildView(
        AdapterTestState state, Dispatch dispatch, ViewService viewService) {
      final ListAdapter adapter = viewService.buildAdapter();
      return Scaffold(
        appBar: AppBar(
          title: Text('Adapter'),
        ),
        body: ListView.separated(
          itemBuilder: adapter.itemBuilder,
          itemCount: adapter.itemCount,
          separatorBuilder: (context, position) => Divider(
            height: 1,
          ),
        ),
      );
    }
    

    3.state基本数据处理

    • state主要负责数据初始化工作,因此不再赘述

    4.adapter

    • 主要使用的是DynamicFlowAdapter,从上文可以看出,由两部分组成,pool 和 connector
    • 代码示例
    class ListGroupAdapter extends DynamicFlowAdapter<AdapterTestState> {
      ListGroupAdapter()
          : super(pool: <String, Component<Object>>{
              'header': ListHeaderComponent(),
              'cell': ListCellComponent(),
              'footer': ListFooterComponent()
            }, connector: ListGroupConnector());
    }
    
    class ListGroupConnector extends ConnOp<AdapterTestState, List<ItemBean>> {
      @override
      List<ItemBean> get(AdapterTestState state) {
        List<ItemBean> items = [];
        if (state.cellModels.length == 0) {
          return items;
        }
        items.add(ItemBean('header', state.headerModel));
        for (var cellModel in state.cellModels) {
          items.add(ItemBean('cell', cellModel));
        }
        items.add(ItemBean('footer', state.footerStr));
        return items;
      }
    }
    
    • pool:主要由三部分组成,头部视图,cell 单元格,尾部视图,他们通过唯一标识符('header','cell','footer')进行关联,代码顺序不分先后,对应的三个子界面主要通过component组装

    • connector: 连接器,数据源处理,通过ItemBean进行数据源包装,items数组的数据顺序分先后,前边的将会优先展示

    • header代码示例

      • component
       class ListHeaderComponent extends Component<AdapterHeaderModel> {
      ListHeaderComponent()
          : super(
              view: buildView,
              dependencies: Dependencies<AdapterHeaderModel>(
                  adapter: null, slots: <String, Dependent<AdapterHeaderModel>>{}),
            );
       }
      
      
    • view

      Widget buildView(
        AdapterHeaderModel state, Dispatch dispatch, ViewService viewService) {
      return Column(
        children: <Widget>[
          Image.network(state.imageNamed),
          Text(
            state.title,
            style: TextStyle(color: Colors.black),
          ),
          Text(
            state.detailTitle,
            style: TextStyle(color: Colors.black45),
          ),
        ],
      );
      }
      

    如果想查看全部代码可下载demo查看

    Demo地址

    相关文章

      网友评论

          本文标题:fish-redux之 adapter基础使用

          本文链接:https://www.haomeiwen.com/subject/uawkdctx.html