Flutter listview 使用“pull_to_refresh”实现刷新、加载效果_2020-07-11

pull_to_refresh介绍

  • 关于pull_to_refresh的介绍及简单使用可参考 github

快速使用如下:

  • pubspec.yaml使用pub包配置:
dependencies:
      pull_to_refresh: ^1.6.0
  • app全局默认配置
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return RefreshConfiguration(
      headerBuilder: () => WaterDropHeader(),
      // 配置头部默认下拉刷新视图
      footerBuilder: () => ClassicFooter(),
      // 配置底部默认上拉加载视图
      headerTriggerDistance: 80.0,
      // 头部触发刷新的距离
      springDescription:
          SpringDescription(stiffness: 170, damping: 16, mass: 1.9),
      // 自定义弹回动画
      maxOverScrollExtent: 100,
      //The maximum dragging range of the head. Set this property if a rush out of the view area occurs
      maxUnderScrollExtent: 0,
      // Maximum dragging range at the bottom
      enableScrollWhenRefreshCompleted: true,
      //This property is incompatible with PageView and TabBarView. If you need TabBarView to slide left and right, you need to set it to true.
      enableLoadingWhenFailed: true,
      //In the case of load failure, users can still trigger more loads by gesture pull-up.
      hideFooterWhenNotFull: false,
      // Disable pull-up to load more functionality when Viewport is less than one screen
      enableBallisticLoad: true,
      // trigger load more by BallisticScrollActivity
      child: MaterialApp(
      ......
  • 页面中配合listView使用
import 'package:pull_to_refresh/pull_to_refresh.dart';
...
  //每页显示数量
  static const int PAGE_SIZE = 10;
  //当前为第几页
  int page = 1;
  //是否加载过数据
  bool loaded;
  //是否允许上拉
  bool _enablePullUp = true;
  //listview数据源
  List<OrderModel> orderItems = [];
  //刷新加载控制器
  RefreshController _refreshController =
      RefreshController(initialRefresh: false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("我的订单"),
      ),
      body: _buildBody(),
    );
  }

///构建body部分widget
_buildListData() {
    //给listview增加父节点SmartRefresher
    return SmartRefresher(
      ///可在此通过header:和footer:指定个性效果
      //允许下拉
      enablePullDown: true,
      //允许上拉加载
      enablePullUp: _enablePullUp,
      //控制器
      controller: _refreshController,
      //刷新回调方法
      onRefresh: _onRefresh,
      //加载下一页回调
      onLoading: _onLoading,
      child: ListView.builder(
        itemBuilder: (c, i) => ItemOrder(orderItems[i]),
        itemCount: orderItems.length,
      ),
    );
  }

  void _onRefresh() async {
    _loadData(true);
  }

  void _onLoading() async {
    _loadData(false);
  }

  void _initData() async {
    _loadData(true);
  }
  _loadData(final bool onRefresh) async {
    int pageNum;
    if(onRefresh){
      pageNum = 1;
    }else{
      pageNum = page+1;
    }
    Map<String, dynamic> query = new Map();
    query['pageNum'] = pageNum;
    query['pageSize'] = PAGE_SIZE;
    Response response = await HttpManager().get(Api.OUT_ORDER_LIST, query: query);
    if(response != null && response.statusCode == HttpStatus.ok){
      ResponseData responseData = ResponseData.fromJsonMap(response.data);
      if(responseData.isSuccess() && responseData.result != null) {
        dynamic result = responseData.result;
        PageResult pageResult = PageResult.fromJson(result);
        if(pageResult.pageNum == pageResult.pages){
          _enablePullUp = false;
        }
        if (pageResult.size > 0 && pageResult.rows != null &&
            pageResult.rows.length > 0) {
          page = pageNum;
          List<dynamic> rows = pageResult.rows;
          if (onRefresh) {
            loaded = true;
            orderItems.clear();
            _addList(rows);
            _refreshController.refreshCompleted();
          }else{
            _addList(rows);
            if (mounted) setState(() {});
            _refreshController.loadComplete();
          }
        }
        setState(() {
        });
      }
    }
  }
  _addList(List<dynamic> rows){
    for (int i = 0; i < rows.length; i++) {
      OrderModel item = OrderModel.fromJson(rows[i]);
      if (item != null) {
        orderItems.add(item);
      }
    }
  }
...

以上就能很方便的实现下拉刷新和上拉翻页功能,pull_to_refresh预设了几种常用的效果


1594310600369.jpg

如果对现有的各种效果不太满意,还可以自己根据模板编写个性效果

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355