Basic use of adapter in fish Redux

Keywords: Flutter

Introduction to official documents

The adapter is fish_ The optimized encapsulation of listView by Redux team is applicable to long list rendering. There are three implementation methods:

  • The DynamicFlowAdapter accepts data drivers of array types
  • The StaticFlowAdapter accepts a data-driven map type
  • CustomAdapter custom 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;
  }
}
  • It is mainly composed of two parts: adapter and connector
  • The adapter pool declaration depends on the component and is marked internally by a unique identifier. Note that the unique identifier in the connector needs to be the same
  • During the operation of the adapter connector data source, you can see that the ListGroupConnector handles the data source. The unique identifier must be consistent with that in the adapter pool. The data source is encapsulated through fish_ ItemBean issued by Redux
  1. StaticFlowAdapter

class SomeStaticAdapter extends StaticFlowAdapter<PageState> {
  SomeStaticAdapter()
    : super(
      slots: [
        SomeComponent().asDependent(SomeComponenConnectt()),
        TaskAdapter().asDependent(TaskAdapterConnect()),
      ],
    );

  • The StaticFlowAdapter receives data of type map
  • StaticFlowAdapter has no pool attribute, but slots. Other attributes are the same as DynamicFlowAdapter.
  • slots accepts an array in which each element is a component or adapter connected to connect.
  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,
    );

  • The above example is a CustomFlowAdapter. The adapter is a method buildCommentAdapter, which returns a ListAdapter.
  • Build comment adapter generates a view list based on the data.
  • For example, in the example, if commentlist. Length > 0, a comment list is added to the ListAdapter. If there are no comments, an empty view widget is added.

This example is described through the DynamicFlowAdapter. First look at the UI interface

  Interface composition: the ListView construction interface is divided into three parts,

  • head
  • Middle cell array
  • tail

The directory structure is shown in the figure below

1.main-page

  • Code example
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>>[],
        );
}

  • An adapter is associated with a page, mainly through the adapter under dependencies, fish_ The corresponding APIs under Redux are as follows
  /// 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

  • In the view interface, you can get the adapter of the page page through buildabadapter () under viewService, and then create the corresponding UI
  • Here's the viewService. We can take a look at the api information
/// 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});
}

  • Corresponding UI
  • Code example
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 basic data processing

  • state is mainly responsible for data initialization, so I won't repeat it

4.adapter

  • The dynamic flow adapter is mainly used. As can be seen from the above, it consists of two parts, pool and connector
  • Code example
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: it is mainly composed of three parts: head view, cell view and tail view. They are associated through unique identifiers ('header','cell','footer '). The code sequence is in no order. The corresponding three sub interfaces are mainly assembled through component s

  • Connector: connector, data source processing, data source packaging through ItemBean. The data of items array is in order, and the previous one will be displayed first

  • header code example

    • 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),
        ),
      ],
    );
    }
    

If you want to view all the code, you can download the demo to view it

Demo address

 



Author: the desolation that can't be reflected by lights, wine and green
Link: https://www.jianshu.com/p/3cde1df28a22
Source: Jianshu
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.

Posted by apulmca2k4 on Mon, 20 Sep 2021 00:32:17 -0700