alibaba / fish-redux

An assembled flutter application framework.
https://github.com/alibaba/fish-redux
Apache License 2.0
7.33k stars 844 forks source link

能详细讲一下Adapter的用法么 #61

Closed jefferybai closed 5 years ago

jefferybai commented 5 years ago

比如pool代表什么意思?

ToDoListAdapter是怎么把_ToDoListConnector的数据传递到pool里面的?

adapter关联的是一个list类型的connector不应该builder出一个ListView么?为什么通过adapter.itemBuilder出了一个item?

还有那三个Aapter分别用在什么场合?

guodf commented 5 years ago

比如pool代表什么意思?

pool是DynamicFlowAdapter中的字段,从类型可以看出是一个map类型,一个自定义符串做key和一个Component做value,Component就是我们页面要显示的UI组件这个好理解吧。页面上要像列表一样展示的Component要定义在pool中。

ToDoListAdapter是怎么把_ToDoListConnector的数据传递到pool里面的?

那么key有什么用?因为Component需要一些初始数据那么数据从哪来呢?就是通过key来的,这个key在哪赋值的呢?当然是在connector中赋值的,重写get方法时就在为这个key赋值。

adapter关联的是一个list类型的connector不应该builder出一个ListView么?为什么通过adapter.itemBuilder出了一个item?

这并不是说adapter关联一个list就一定要builder一个ListView类型,这只是说明你将要显示的UI是由多个相同格式的Item组成的widgets

还有那三个Aapter分别用在什么场合?

  1. DynamicFlowAdapter定义的是模板,数据都是在connector的get中设置的,当有类似列表这样形式的数据时用DynamicFlowAdapter
  2. StaticFlowAdapter定义的也是模板,不过这个模板都是固定的,每个模板都要一个connector与之对应
  3. Adapter暂时没有使用
jefferybai commented 5 years ago

@guodf 谢谢, 另外,请问你们好用的屏幕适配方案么?

jefferybai commented 5 years ago

@guodf DynamicFlowAdapter的数据结构大致相同, 渲染出来的结果也大致相同。 而StaticFlowAdapter是定制化的模板? 可以这样理解么? 另外,能否提供一个StaticFlowAdapter的example,感谢

zjuwjf commented 5 years ago

@guodf DynamicFlowAdapter的数据结构大致相同, 渲染出来的结果也大致相同。 而StaticFlowAdapter是定制化的模板? 可以这样理解么? 另外,能否提供一个StaticFlowAdapter的example,感谢

你考虑下一个页面有多种子类目,它们是各种子组件的顺序组合的结果, [A,B,C,D,E,F,G,...], 不同的子类目都是上面的子集,比如[A,B,C,F,G], [B,C,D,E,G], 而同时描述它数据是一个maplike的对象,符合上面两点的场景下,使用StaticFlowAdapter就会有非常大的收益。

guodf commented 5 years ago

其实fish-redux我使用还超不过24小时,里面很多东西还没有使用,很多场景还没有遇见。 之所以使用fish-redux是因为我遇到了页面需要局部刷新的问题,其它状态管理扩展都没有解决这个问题,而fish-redux里面提到了这个问题,这是我选择它的初衷。

jefferybai commented 5 years ago

@guodf 你都是用的什么适配方案?

guodf commented 5 years ago

没有用,刚入门,还没有到那一步呢

jefferybai commented 5 years ago

@zjuwjf 官方是否有提供StaticFlowAdapter的例子

guodf commented 5 years ago

我对官方的例子简单改动了一下,你理解一下StaticFlowAdapter的用法: 替换example的page.dart中的代码,如下:

import 'package:fish_redux/fish_redux.dart';

import 'effect.dart';
import 'list_adapter/adapter.dart';
import 'reducer.dart';
import 'report_component/component.dart';
import 'state.dart';

import 'view.dart';

class ToDoListPage extends Page<PageState, Map<String, dynamic>> {
  ToDoListPage()
      : super(
          initState: initState,
          effect: buildEffect(),
          reducer: buildReducer(),
          view: buildView,
          dependencies: Dependencies<PageState>(
              adapter:StaticFlowAdapter<PageState>(
                slots: <Dependent<PageState>>[
                  ReportComponent().asDependent(ReportConnector()),
                  ToDoListAdapter().asDependent(ToDoListAdapterConnector()),
                  ReportComponent().asDependent(ReportConnector()),
                ]
              ) ,
              slots: <String, Dependent<PageState>>{
                'report': ReportConnector() + ReportComponent()
              }),
          middlewares: <Middleware<PageState>>[
            logMiddleware(tag: 'ToDoListPage'),
          ],
        );
}

class ToDoListAdapterConnector extends ConnOp<PageState, PageState>{
  @override
  PageState get(PageState state) {
    return state;
  }
  @override
  void set(PageState state, PageState substate) {
    super.set(state, substate);
  }
}

官网给出的ToDoListAdapter继承DynamicFlowAdapter其实没有必要这么做,之所以这么做是告诉你可以通过这种方式将adapter放在单独的目录中,方便代码结构管理。 官方的list_adapter/adapter.dart改成下面这样,同样可以达到效果:

import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/component.dart';
import 'reducer.dart';

 DynamicFlowAdapter buildAdapter(){
   return DynamicFlowAdapter<PageState> (
          pool: <String, Component<Object>>{
            'toDo': ToDoComponent(),
          },
          connector: _ToDoListConnector(),
          reducer: buildReducer(),
        );
}

class _ToDoListConnector implements Connector<PageState, List<ItemBean>> {
  @override
  List<ItemBean> get(PageState state) {
    if (state.toDos?.isNotEmpty == true) {
      return state.toDos
          .map<ItemBean>((ToDoState data) => ItemBean('toDo', data))
          .toList(growable: true);
    } else {
      return <ItemBean>[];
    }
  }

  @override
  void set(PageState state, List<ItemBean> toDos) {
    if (toDos?.isNotEmpty == true) {
      state.toDos = List<ToDoState>.from(
          toDos.map<ToDoState>((ItemBean bean) => bean.data).toList());
    } else {
      state.toDos = <ToDoState>[];
    }
  }
}
zjuwjf commented 5 years ago

补充下: StaticFlowAdapter 是固定顺序编排下的列表,根据connector.get是否为空来决定对应的item是否存在。