Flutter刷新实践 2022-07-18 周一

简介

下拉刷新,下拉加载更多,是一个比较普遍的功能。比如一个接口返回一个列表,数据有上百项,甚至更多,一次性全部返回显示不大合适。所以,一般接口会进行分页,提供一个page和pageSize参数,一小部分一小部分地来取数据。
虽然iOS原生提供这些功能,但是效果很差,一般都会求助于第三方库。Flutter也一样,这个功能也会用第三方库。

添加

flutter pub add easy_refresh
dependencies:
  easy_refresh: ^3.0.2+1

链接地址

easy_refresh: ^3.0.2+1

flutter_easy_refresh

3.0是最近的一次大升级,pub上的地址都变了。以前的名字叫flutter_easy_refresh

构造方法

这个组件用的最多的是ListView。用法和手势差不多,将需要上拉下拉的ListView作为子组件。

/// 默认的构造方法
const EasyRefresh({
    Key? key,
    required this.child,
//... ....
})

/// 第2种构造方法
const EasyRefresh.builder({
    Key? key,
    required this.childBuilder,
//... ....
})
  • 这个和ListView的构造方法很像,大多数情况下,使用默认的构造方法就可以了。

  • ListView嵌套的时候,就应该带builder的构造方法。physics代表ListView是否可以滑动。将需要上拉下拉的指定为可滑动,内部嵌套的指定为不可滑动。

  • ListView嵌套的情况,内部ListView经常会将shrinkWrap设置为true,这里不能这么做。

  • 参数里只有一个代表子组件的child是必选的,其他的都是可选的。这个也和手势很像。但是实际使用的时候,就这一个参数其实没什么用,需要其他参数一起配合使用。

上拉下拉

这是这个组件最核心的两个功能。就像onTap对于GestureDetector组件一样。虽然是可选的,但是大多数情况,这两个参数都是要给的。

  /// Refresh callback.
  /// Triggered on refresh.
  /// When null, disable refresh.
  /// The Header current state is [IndicatorMode.processing].
  /// More see [IndicatorNotifier.onTask].
  final FutureOr Function()? onRefresh;

  /// Load callback.
  /// Triggered on load.
  /// When null, disable load.
  /// The Footer current state is [IndicatorMode.processing].
  /// More see [IndicatorNotifier.onTask].
  final FutureOr Function()? onLoad;
  • 这里给FutureOr类型可以简单看做Future;一般数据获取都是异步的,例外的情况很少。

  • 一般这两个方法都会调用网络数据访问的API,并且一般会有page,pageSize两个参数。

  • 还有一个要考虑的问题就是确定是否有数据。这个在onLoad方法中需要确定。如果已经没有数据了,那么就不需要再进行网络请求了,同时也要给出相应的提示。

  • 判断是否有更多数据一般有两种方法。一种是接口给出数据的总数,客户端端根据已经收到的数量来判断是否结束。
    另外一种方法是判断本次返回的数量,与pageSize进行比较。如果还有更多数据,那么本次返回的数据量就是pageSize;如果不足的话,那么当前返回的就是最后一点数据了,是最后一个有数据的接口。(就像整除里面的求余,余数肯定比除数要小)

头和尾

  • 在上拉和下拉过程中,在网络数据请求结束的时候,有一些状态改变,这个都是通过头和尾这两个视图来表现的。可以简单地理解为是ListView的头和尾。

  • 这两个参数是可选的,不给的话,会提供默认的视图。大多数情况下,用默认的也可以凑合。

  /// Header indicator.
  final Header? header;

  /// Footer indicator.
  final Footer? footer;
  • Header和Footer都继承自Indicator。提供了好多种Header和Footer,可以根据需要进行选择。ClassicHeader和ClassicFooter可以满足大多数情况。

控制器

  • 和TextField组件类似,提供了一个控制器进行更多的自定义。比如,用代码进行额外的刷新,加载更多,用代码结束刷新或者加载更多等等功能。

  • 大多数情况可以不需要用这个控制器。需要更多控制的时候,可以考虑加。

  • 要注意的是,和TextField组件的控制器类似,控制器需要在组件外部进行初始化。用完之后,要调用dispose方法进行销毁。

  • 如果要使用控制器,那么就要把默认的两个变量改为true

  /// Take over the completion event of the refresh task.
  /// Finish the refresh with [finishRefresh] and return the result.
  final bool controlFinishRefresh;

  /// Take over the completion event of the load task.
  /// Finish the load with [finishLoad] and return the result.
  final bool controlFinishLoad;

  EasyRefreshController({
    this.controlFinishRefresh = false,
    this.controlFinishLoad = false,
  });

简化的例子

  • 数据逻辑部分(logic):
  ///下拉刷新上拉加载固定写法
  List dataList = [];
  int pageNum = 1;
  final int pageSize = 20;
  bool hadMore = true;
  EasyRefreshController easyRefreshController = EasyRefreshController(
    controlFinishRefresh: true,
    controlFinishLoad: true,
  );

  /// 下拉刷新
  Future refreshData() async {
    pageNum = 1;
    hadMore = true;
    dataList = [];
    
    getDataList();
  }

  /// 上拉加载更多
  Future loadMoreData() async {
    if (hadMore) {
      pageNum++;
      getDataList();
    } else {
      easyRefreshController.finishLoad(IndicatorResult.noMore);
    }
  }

  /// 从网络取数据
  void getDataList() {
    NetworkApi.getDataListFromRemote(
        pageNum: pageNum,
        pageSize: pageSize,
        success: (response) {
          List list = response['data'];
          if (list.length < pageSize) {
            hadMore = false;
          } else {
            hadMore = true;
          }
          if (dataList.isEmpty) {
            easyRefreshController.finishRefresh();
          } else {
            easyRefreshController.finishLoad(
                hadMore ? IndicatorResult.success : IndicatorResult.noMore);
          }
          dataList.addAll(list);

          update();
        },
        fail: (fail) {});
  }
  //下拉刷新上拉加载固定写法

@override
  void onClose() {
    easyRefreshController.dispose();
    super.onClose();
  }
  • 界面相关部分(view)
EasyRefresh(
    controller: logic.easyRefreshController,
    header: ClassicHeader(),
    footer: ClassicFooter,
    onRefresh: logic.refreshData,
    onLoad: logic.loadMoreData,
    child: ListView.builder(
        itemCount: logic.dataList.length,
        itemBuilder: (BuildContext context, int index) {
            Map item = logic.dataList[index] ?? {};
            String name = item['name'] ?? '';
            return Container(
                height: 44.h,
                child: Text(name),
            );
        }
    ),
)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容