Flutter 17: 图解 ListView 下拉刷新与上拉加载 (一)【flutter_refresh】

简介: 0 基础学习 Flutter,第十七步:ListView 上拉加载更多与下拉刷新,解决方案一!

      小菜上次学 ListView 时,只学习了一下异步请求数据加载新闻和 Loading 等待的小知识点,但对于新闻列表数据的更新和加载更多是必不可少的,而实现【下拉刷新】与【上划加载更多】的方式有很多种,今天小菜整理一下使用三方库 flutter_refresh 来实现列表的数据更新。
      小菜也是再偶然间看到有大神用到这个三方库的,小菜想要尝试的原因主要是因为一是因为 flutter_refresh 集成很简单,不用单独写头部样式和底部加载时的 loading 等;二是小菜技术太有限,对 Flutter 的未知有太多,想多尝试几种方式。

集成方式

  1. pubspec.yaml 中 添加 flutter_refresh : ^0.0.2,并同步 packages get
  2. 在相应的 .dart 文件中添加引用 import 'package:flutter_refresh/flutter_refresh.dart';
  3. 数据加载时暂时不用 ListView 变更为 new Refresh,小菜主要是处理 onHeaderRefresh 下拉刷新onFooterRefresh 底部刷新 两个方法中的数据处理。小菜的测试接口需要根据每一页的最后一个新闻ID 和 整个的新闻数量为参数值进行处理。

// 顶部刷新
Future<Null> onHeaderRefresh() {
  return new Future.delayed(new Duration(seconds: 2), () {
    setState(() {
      rowNumber = 0;
      lastFileID = '0';
      newsListBean = null;
      getNewsData(lastFileID, rowNumber);
    });
  });
}
// 底部刷新
Future<Null> onFooterRefresh() async {
  return new Future.delayed(new Duration(seconds: 2), () {
    setState(() {
      getNewsData(lastFileID, rowNumber);
    });
  });
}
// 接口数据处理
getNewsData(var lastID, var rowNum) async {
  await http
      .get(
          'https://...?lastFileID=${lastID}&rowNumber=${rowNum}')
      .then((response) {
    if (response.statusCode == 200) {
      var jsonRes = json.decode(response.body);
      newsListBean = NewsListBean(jsonRes);
      if (lastID == '0' && rowNum==0 && dataItems != null) {
         dataItems.clear();
      }
      setState(() {
        if (newsListBean != null &&
            newsListBean.list != null &&
            newsListBean.list.length > 0) {
          for (int i = 0; i < newsListBean.list.length; i++) {
            dataItems.add(newsListBean.list[i]);
          }
          lastFileID = newsListBean.list[newsListBean.list.length - 1].fileID
              .toString();
          rowNumber += newsListBean.list.length;
        } else {}
      });
    }
  });
}

Widget childFreshWidget() {
  Widget childFreWi;
  if (dataItems != null && dataItems.length != 0) {
    childFreWi = new Padding(
      padding: EdgeInsets.all(6.0),
      child: new Refresh(
        onFooterRefresh: onFooterRefresh,
        onHeaderRefresh: onHeaderRefresh,
        childBuilder: (BuildContext context,
            {ScrollController controller, ScrollPhysics physics}) {
          return new Container(
              child: new ListView.builder(
            physics: physics,
            controller: controller,
            itemCount: rowNumber,
            itemBuilder: (context, item) {
              return buildListData(context, dataItems[item]);
            },
          ));
        },
      ),
    );
  } else {
    childFreWi = new Stack(
      children: <Widget>[
        new Padding(
          padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 35.0),
          child: new Center( child: SpinKitFadingCircle( color: Colors.blueAccent, size: 30.0, ), ),
        ),
        new Padding(
          padding: new EdgeInsets.fromLTRB(0.0, 35.0, 0.0, 0.0),
          child: new Center( child: new Text('正在加载中,莫着急哦~'), ),
        ),
      ],
    );
  }
  return childFreWi;
}

下拉刷新

上拉加载更多

问题小结

      小菜在测试过程中遇到了很多的小问题,现在逐一整理一下。

问题一:初始化进入页面后,加载完第一页之后刷新数据不加载,第二次刷新数据才加载,且加载的是上一次刷新的数据?
解决方式:
  1. 进入页面时调用数据接口 initState(),为了保证第一次正常加载;
  2. getNewsData() 中一定一定要添加 setState(() {}); 小菜在测试时,每次刷新接口都会正常调用,但是都是第二次刷新才加载第一次刷新的数据,接口是正常的,但是数据总是慢一拍,小菜测试发现因为没有用 setState(() {}); 以后一定要注意,这样才可以实时进行更新。
问题二:下拉刷新过程中,接口数据重复加载?
解决方式:

      小菜目前还没有涉及缓存等方面的,单纯的一个下拉刷新应该是重新调用初始的接口,首先要清空列表,不然接口数据重复实实在在会出现的。

Future<Null> onHeaderRefresh() {
  return new Future.delayed(new Duration(seconds: 2), () {
    setState(() {
      rowNumber = 0;
      lastFileID = '0';
      if (dataItems != null) {
         dataItems.clear();
      }
      getNewsData(lastFileID, rowNumber);
    });
  });
}
问题三:根据问题二的解决方案,显示正常,但是运行时 Log 报错,提示 Widget 已创建?

解决方案:

      小菜测试了很久,把这个判断列表制空从 onHeaderRefresh() 中移到数据处理的 getNewsData() 方法中,虽然不是非常理解,但是问题可以正常解决,小菜的理解是 onHeaderRefresh() 中处理的是数据和 Widget,而小菜自己的方法中是单纯的数据处理。

if (lastID == '0' && rowNum==0 && dataItems != null) {
  dataItems.clear();
}

      小菜刚接触 Flutter 时间不长,还有很多不清楚和不理解的地方,如果又不对的地方还希望多多指出。

目录
相关文章
|
7月前
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套 在 Flutter 中,ListView 和 PageView 是两个常用的控件,它们可以用于滑动展示大量内容的场景,且支持各种嵌套方式,本文将介绍其中的一些花式嵌套方式。
285 0
Flutter ListView懒加载(滑动不加载,停止滑动加载)
前言:为了更好的减小网络的带宽,使得列表更加流畅,我们需要了解懒加载,也称延迟加载。关于上一章的登录界面,各位属实难为我了,我也在求ui小姐姐,各位点点赞给我点动力吧~
Flutter ScrollView嵌套ListView滑动冲突
Flutter ScrollView嵌套ListView滑动冲突
1298 0
|
1月前
|
容器
Flutter下拉刷新上拉加载的简单实现方式一
Flutter下拉刷新上拉加载的简单实现方式一
50 2
|
4月前
|
UED
Flutter之ListView实现自动滑动到底部
Flutter之ListView实现自动滑动到底部
230 1
|
5月前
flutter- Row Column Expanded ListView
flutter- Row Column Expanded ListView
|
5月前
Flutter 列表学习(listview,gridview,ExpansionTile,ScrollController,RefreshIndicator)
Flutter 列表学习(listview,gridview,ExpansionTile,ScrollController,RefreshIndicator)
|
7月前
|
开发框架 前端开发 UED
【Flutter前端技术开发专栏】Flutter中的下拉刷新与上拉加载更多
【4月更文挑战第30天】在Flutter移动应用开发中,下拉刷新和上拉加载更多能提升用户体验和用户参与度。通过`RefreshIndicator`组件和`ScrollController`实现下拉刷新与上拉加载。`RefreshIndicator`包裹可滚动Widget,`ScrollController`监听滚动事件以判断是否到达底部。性能优化包括避免重复加载、使用防抖技术和异步加载数据。参考Flutter官方文档和相关教程可进一步学习。
421 0
【Flutter前端技术开发专栏】Flutter中的下拉刷新与上拉加载更多
|
7月前
Flutter.源码分析.flutter/packages/flutter/lib/src/widgets/scroll_view.dart/ListView
Flutter.源码分析.flutter/packages/flutter/lib/src/widgets/scroll_view.dart/ListView
66 0
|
缓存
【布局 widget】Flutter ListView
ListView 是最常用的滚动 widget,也是布局 widget。它在滚动方向上一个接一个地显示它的 child。
258 0
【布局 widget】Flutter ListView