Flutter之Fish_Redux实战训练(二)

本文在简书首发,如有转载,请注明出处
https://www.jianshu.com/p/010dc147cfaa

前言

上一节写了一个登录的Demo,用来阐释fish_redux的使用方法。想看的同学可以点击下方的连接
https://www.jianshu.com/p/591088f3bc73
这篇博客,将会再深入点讲解fish_redux的使用方式,通过实战的方式,让大家了解到fish_redux的adapter和component的概念和用法。

代码依旧使用上一篇博客的代码,新增页面,使用adapter和component

代码地址:https://github.com/wjbd/fish_redux_demo

component的概念

component意为组件的意思,组件是对局部的展示和功能的封装。组件是对视图的分治,也是对数据的分治。通过逐层分治,我们将复杂的页面和数据切分为相互独立的小模块。这将利于团队内的协作开发。
下面盗两张阿里公开闲鱼fish_redux的案例demo,让大家可以更清晰的组件在flutter页面中的形式。

image

image

adapter的概念

在Android开发当中所有人都得写过适配器,所有对这个概念应该相当熟悉,但是在fish_redux当中,adapter不仅仅充当了适配器的概念,更是超前了一步。

官方定义的adapter:面向 ListView 场景的分治设计 Adapter。
一个ListView一个adpter,这看上去非常像Android的设计,但是fish_redux的adapter概念比Android的adapter走的更远。
一个 Adapter 是可以由多个 Component 和 Adapter 组合而成
adapter的容器在fish_redux当中有两种,下面还是使用官方的图来简单说明一下:

  • StaicFlowAdapter


    image
  • DynamicFlowAdapter


    image

    作者这里还是用DynamicFlowAdapter,因为更符合原生Android开发的思想。

撸码开始

通过实战让大家更清楚的了解adapter和comoponent,不然纸上谈兵,还是不了解这些代码的实际应用。
本次的demo是在上节demo基础上改造的,增加了listview功能,旨在使用fish_redux当中的adapter和component,同时还增加了使用fish_redux使用dialog的例子。

先看看代码结构图

image

在HomePage下面有WeatherComponent,WeatherAdapter两个组件,同时WeatherComponent下面还有一个DialogComponent组件。

本博客中只展示HomePage页面的详细代码,其他的请参考代码地址:

代码地址:https://github.com/wjbd/fish_redux_demo

page

class HomePage extends Page<HomeState, Map<String, dynamic>> {
  HomePage()
      : super(
          initState: initState,
          effect: buildEffect(),
          view: buildView,
          dependencies: Dependencies<HomeState>(
            adapter: NoneConn<HomeState>() + WeatherAdapter(),
          ),
        );
}

action

enum HomeAction { refresh }

class HomeActionCreator {
  static Action onRefresh() {
    return const Action(HomeAction.refresh);
  }

}

effect

Effect<HomeState> buildEffect() {
  return combineEffects(<Object, Effect<HomeState>>{
    Lifecycle.initState: _init,
    HomeAction.refresh: _onRefresh,
  });
}

void _init(Action action, Context<HomeState> ctx) {
  ctx.dispatch(HomeActionCreator.onRefresh());
}

void _onRefresh(Action action, Context<HomeState> ctx) async {
  Map<String, dynamic> params = {
    'city': '北京',
  };
  Response response = await Dio().post(
    "https://www.apiopen.top/weatherApi",
    queryParameters: params,
  );
  int code = response.data['code'];
  String msg = response.data['message'];
  Map<String, dynamic> data = response.data['data'];
  List list = data['forecast'];
  List<Weather> weatherList = list.map((m) {
    return new Weather.fromJson(m);
  }).toList();
  if (code == 200) {
    ctx.state.refreshController.refreshCompleted();
    ctx.dispatch(WeatherActionCreator.onSetNewData(weatherList));
    Fluttertoast.showToast(msg: '获取天气信息成功');
  } else {
    ctx.state.refreshController.refreshFailed();
    Fluttertoast.showToast(msg: "获取天气信息失败:$msg");
  }
}

state

class HomeState implements Cloneable<HomeState> {
  RefreshController refreshController;
  List<Weather> list;
  @override
  HomeState clone() {
    return HomeState()
      ..list = list
      ..refreshController = refreshController;
  }
}

HomeState initState(Map<String, dynamic> args) {
  HomeState state = new HomeState();
  state.refreshController = new RefreshController(initialRefresh: false);
  state.list = new List();
  return state;
}

view

Widget buildView(HomeState state, Dispatch dispatch, ViewService viewService) {
  final ListAdapter adapter = viewService.buildAdapter();
  return Scaffold(
    appBar: PreferredSize(
      preferredSize: Size.fromHeight(50.0),
      child: AppBar(
        automaticallyImplyLeading: false,
        centerTitle: true,
        elevation: 0,
        title: Text('首页'),
      ),
    ),
    body: Container(
      child: SmartRefresher(
        header: ClassicHeader(),
        controller: state.refreshController,
        onRefresh: () {
          dispatch(HomeActionCreator.onRefresh());
        },
        child: ListView.builder(
          itemCount: adapter.itemCount,
          itemBuilder: adapter.itemBuilder,
        ),
      ),
    ),
  );
}

在fish_redux中dialog的使用方法

WeatherComponent的Effect

Effect<WeatherState> buildEffect() {
  return combineEffects(<Object, Effect<WeatherState>>{
    WeatherAction.showDialog: _onShowDialog,
  });
}

void _onShowDialog(Action action, Context<WeatherState> ctx) {
  showDialog(
    context: ctx.context,
    builder: (BuildContext context) {
      return ctx.buildComponent('dialog');
    },
  );
}

总结

  • 本次demo代码量比较大,在博客展示显示太累赘,大家可以去github上查看详细代码,仔细阅读。
  • adapter和component属于fish_redux的核心功能,对于代码的扩展分治起到了非常好的功能,堪称划分模块神器,让代码的划分更细,找错误更方便,模块划分也更好,容易分任务下去。
  • 学习成本真的大,想要把这块代码搞清楚,如果不手动去敲一下,大部分的人应该很难理解Component和Adapter,这里也是借着简单的Demo,简化fish_redux的学习过程。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 154,545评论 3 353
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 65,620评论 1 282
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 104,437评论 0 234
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,149评论 0 200
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,429评论 3 281
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,029评论 1 199
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,455评论 2 305
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,138评论 0 191
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,778评论 1 234
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,133评论 2 236
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,656评论 1 253
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,030评论 2 244
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,554评论 3 226
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,903评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,606评论 0 190
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,005评论 2 260
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,969评论 2 255