Flutter 下拉刷新、上拉加载

article/2025/10/12 19:08:30

Flutter 下拉刷新、上拉加载有很多第三方插件,本文使用插件为:pull_to_refresh

目前pull_to_refresh在pub.dev上的使用情况:
在这里插入图片描述

刷新header的类型:
ClassicHeader
在这里插入图片描述

  const ClassicHeader({Key? key,RefreshStyle refreshStyle: RefreshStyle.Follow,double height: 60.0,Duration completeDuration: const Duration(milliseconds: 600),this.outerBuilder,this.textStyle: const TextStyle(color: Colors.grey),this.releaseText,//松手加载this.refreshingText,//正在加载this.canTwoLevelIcon,this.twoLevelView,this.canTwoLevelText,this.completeText,//加载完成this.failedText,this.idleText,//下拉加载this.iconPos: IconPosition.left,this.spacing: 15.0,this.refreshingIcon,this.failedIcon: const Icon(Icons.error, color: Colors.grey),this.completeIcon: const Icon(Icons.done, color: Colors.grey),this.idleIcon = const Icon(Icons.arrow_downward, color: Colors.grey),this.releaseIcon = const Icon(Icons.refresh, color: Colors.grey),})

WaterDropHeader
在这里插入图片描述

  const WaterDropHeader({Key? key,this.refresh,this.complete,Duration completeDuration: const Duration(milliseconds: 600),this.failed,this.waterDropColor: Colors.grey,this.idleIcon: const Icon(Icons.autorenew,size: 15,color: Colors.white,),   

MaterialClassicHeader
在这里插入图片描述

  const MaterialClassicHeader({Key? key,double height: 80.0,this.semanticsLabel,this.semanticsValue,this.color,double offset: 0,this.distance: 50.0,this.backgroundColor,}) 

WaterDropMaterialHeader
在这里插入图片描述

  const WaterDropMaterialHeader({Key? key,String? semanticsLabel,double distance: 60.0,double offset: 0,String? semanticsValue,Color color: Colors.white,Color? backgroundColor,})

BezierHeader
在这里插入图片描述

  BezierHeader({this.child: const Text(""),this.onOffsetChange,this.onModeChange,this.readyRefresh,this.enableChildOverflow: false,this.endRefresh,this.onResetValue,this.dismissType: BezierDismissType.RectSpread,this.rectHeight: 70,this.bezierColor})

TwoLevelHeader
在这里插入图片描述

  const TwoLevelHeader({Key? key,this.height: 80.0,this.decoration,this.displayAlignment: TwoLevelDisplayAlignment.fromBottom,this.completeDuration: const Duration(milliseconds: 600),this.textStyle: const TextStyle(color: const Color(0xff555555)),this.releaseText,this.refreshingText,this.canTwoLevelIcon,this.canTwoLevelText,this.completeText,this.failedText,this.idleText,this.iconPos: IconPosition.left,this.spacing: 15.0,this.refreshingIcon,this.failedIcon: const Icon(Icons.error, color: Colors.grey),this.completeIcon: const Icon(Icons.done, color: Colors.grey),this.idleIcon = const Icon(Icons.arrow_downward, color: Colors.grey),this.releaseIcon = const Icon(Icons.refresh, color: Colors.grey),this.twoLevelWidget});

CustomHeader
在这里插入图片描述

const CustomHeader({Key? key,required this.builder,  //HeaderBuilder(BuildContext context, RefreshStatus? mode);第二个参数刷新的状态,根据状态显示对应的刷新内容this.readyToRefresh, //准备刷新的回调this.endRefresh,//结束刷新的回调this.onOffsetChange,//下拉距离改变的回调this.onModeChange,//下拉状态改变的回调--RefreshStatusthis.onResetValue,double height: 60.0,Duration completeDuration: const Duration(milliseconds: 600),RefreshStyle refreshStyle: RefreshStyle.Follow, //设置下拉的样式})

刷新fotter的类型:
ClassicFooter
在这里插入图片描述

  const ClassicFooter({Key? key,VoidCallback? onClick,LoadStyle loadStyle: LoadStyle.ShowAlways,double height: 60.0,this.outerBuilder,this.textStyle: const TextStyle(color: Colors.grey),this.loadingText,this.noDataText,this.noMoreIcon,this.idleText,this.failedText,this.canLoadingText,this.failedIcon: const Icon(Icons.error, color: Colors.grey),this.iconPos: IconPosition.left,this.spacing: 15.0,this.completeDuration: const Duration(milliseconds: 300),this.loadingIcon,this.canLoadingIcon: const Icon(Icons.autorenew, color: Colors.grey),this.idleIcon = const Icon(Icons.arrow_upward, color: Colors.grey),})

CustomFooter
在这里插入图片描述

  const CustomFooter({Key? key,double height: 60.0,this.onModeChange,this.onOffsetChange,this.readyLoading,this.endLoading,LoadStyle loadStyle: LoadStyle.ShowAlways,//下拉加载样式required this.builder,Function? onClick,})

页面刷新、加载通用模块可以进行封装,封装header继承ClassicHeader,封装fotter继承ClassicFooter

class RefreshHeader extends ClassicHeader {}class LoadingFotter extends ClassicFooter {}

代码示例

import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';class RefreshPage extends StatefulWidget {RefreshPage({Key? key}) : super(key: key);@override_RefreshPageState createState() => _RefreshPageState();
}class _RefreshPageState extends State<RefreshPage> {// 定义原始数据List<String> items = ["1", "2", "3", "4", "5", "6", "7", "8"];// 定义刷新控制器RefreshController _refreshController =RefreshController(initialRefresh: false);void _onRefresh() async {// 模拟网络请求,此处延时1秒await Future.delayed(Duration(milliseconds: 1000));// 刷新成功,数据恢复原样items = ["1", "2", "3", "4", "5", "6", "7", "8"];if (mounted) {setState(() {});}// 重置获取数据LoadStatus_refreshController.refreshCompleted(resetFooterState: true);}void _onLoading() async {// 模拟网络请求,此处延时1秒await Future.delayed(Duration(milliseconds: 1000));// 每次模拟加载数据,等到数据加载到20个为止,模拟数据都获取完成, 并设置LoadStatusif (items.length >= 20) {_refreshController.loadNoData();return;}//每次加载两个数据items.add((items.length + 1).toString());items.add((items.length + 1).toString());if (mounted) {setState(() {});}_refreshController.loadComplete();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Scaffold'),),body: SmartRefresher(enablePullDown: true, // 下拉刷新enablePullUp: true, // 上拉加载数据// header: ClassicHeader(//   refreshStyle: RefreshStyle.UnFollow,//     refreshingText:'正在加载...',//   releaseText: '松手加载...',//   completeText: '加载完成',//   idleText: '下拉加载',// ),// header: ClassicHeader(),// header: WaterDropHeader(),// header: MaterialClassicHeader(),// header: WaterDropMaterialHeader(),// header: BezierHeader(),// header: TwoLevelHeader(),header: CustomHeader(refreshStyle: RefreshStyle.Behind,builder: (BuildContext context, RefreshStatus? mode) {Widget headerBody;if(mode == RefreshStatus.idle) {headerBody = Text('刷新');}else if(mode == RefreshStatus.refreshing) {headerBody = Text('刷新中...');}else if(mode == RefreshStatus.failed) {headerBody = Text('刷新失败');}else if(mode == RefreshStatus.completed) {headerBody = Text('刷新完成');}else if(mode == RefreshStatus.canRefresh) {headerBody = Text('松手刷新');}else {headerBody = Text("完成");}return Container(height: 55.0,child: Center(child: headerBody),);},),// footer: ClassicFooter(),footer: CustomFooter(// 设置上拉、下拉时的提示内容builder: (context, mode) {Widget body;if (mode == LoadStatus.idle) {body = Text("上拉加载");} else if (mode == LoadStatus.loading) {// body = CupertinoActivityIndicator();body = Text("加载中");} else if (mode == LoadStatus.failed) {body = Text("加载失败");} else if (mode == LoadStatus.canLoading) {body = Text("松手加载");} else {body = Text("没有更多数据");}return Container(height: 55.0,child: Center(child: body),);},),controller: _refreshController,onRefresh: _onRefresh,onLoading: _onLoading,child: ListView.builder(itemBuilder: (c, i) => Card(child: Center(child: Text(items[i]))),itemExtent: 100.0,itemCount: items.length,),),);}
}

特殊情况:

当当前数据不满一个屏幕时,此时展示上拉加载会先加载,然后无数据提示紧跟列表后面,如果示:
在这里插入图片描述
当数据不足一个屏幕时,不进行上拉加载数据的操作
结果图:
在这里插入图片描述
代码示例:

import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';class MePage extends StatefulWidget {MePage({Key? key}) : super(key: key);@override_RefreshPageState createState() => _RefreshPageState();
}class _RefreshPageState extends State<MePage> {// 定义原始数据List<String> items = ["1","2",];bool isLoad = true;// 定义刷新控制器RefreshController _refreshController =RefreshController(initialRefresh: false);@overridevoid initState() {super.initState();}void _onRefresh() async {// 模拟网络请求,此处延时1秒await Future.delayed(Duration(milliseconds: 1000));// 刷新成功,数据恢复原样items = ["1","2","3","4","3","4","3","4",];if (mounted) {setState(() {});}// 重置获取数据LoadStatus_refreshController.refreshCompleted(resetFooterState: true);}void _onLoading() async {// 模拟网络请求,此处延时1秒await Future.delayed(Duration(milliseconds: 1000));// 每次模拟加载数据,等到数据加载到20个为止,模拟数据都获取完成, 并设置LoadStatusif (items.length >= 2) {_refreshController.loadNoData();return;}//每次加载两个数据items.add((items.length + 1).toString());if (mounted) {setState(() {});}_refreshController.loadComplete();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Scaffold'),),body: RefreshConfiguration(footerTriggerDistance: 80,//   dragSpeedRatio: 0.91,hideFooterWhenNotFull: true,headerBuilder: () => ClassicHeader(),footerBuilder: () => ClassicFooter(),child: SmartRefresher(dragStartBehavior: DragStartBehavior.down,enablePullDown: true, // 下拉刷新enablePullUp: true, // 上拉加载数据controller: _refreshController,onRefresh: _onRefresh,onLoading: _onLoading,child: ListView.builder(itemBuilder: (c, i) => Card(child: Center(child: Text(items[i],style: TextStyle(fontSize: 10.0),))),itemExtent: 100.0,itemCount: items.length,),),),);}
}

fotter、header的位置,可以根据需求添加位置和定制样式

RefreshConfiguration说明:

  RefreshConfiguration({Key? key,required this.child,  //Widgetthis.headerBuilder, //下拉刷新header显示内容this.footerBuilder, //上拉加载footer显示内容this.dragSpeedRatio: 1.0,//拖拽速度this.shouldFooterFollowWhenNotFull, //当数据不足一个屏幕,遵循的状态this.enableScrollWhenTwoLevel: true, 两屏时用户是否可以拖动视口this.enableLoadingWhenNoData: false,//当footer处于nomore状态时,是否通过达到footerDistance来触发负载this.enableBallisticRefresh: false,//是否通过BallisticScrollActivity触发刷新this.springDescription: const SpringDescription(mass: 2.2,stiffness: 150,damping: 16,), //自定义弹簧动画this.enableScrollWhenRefreshCompleted: false,//当刷新完成并返回时,用户是否可以拖动viewportthis.enableLoadingWhenFailed: true, //失败时,footer是否可以通过达到footerDistance来触发负载this.twiceTriggerDistance: 150.0,//触发器twoLevel的超滚动距离this.closeTwoLevelDistance: 80.0, //关闭二层的底部穿越距离,前提:enableScrollWhenTwoLevel为truethis.skipCanRefresh: false, //如果到达triggerDistance时需要立即刷新this.maxOverScrollExtent, //超出边缘时的最大顶部滚动距离 --headerthis.enableBallisticLoad: true,//是否通过BallisticScrollActivity触发加载this.maxUnderScrollExtent, //超出边缘时最大底部滚动距离-- fotterthis.headerTriggerDistance: 80.0,//触发刷新的超滚距离this.footerTriggerDistance: 15.0, //触发加载后的距离this.hideFooterWhenNotFull: false, //当listView数据很小(不够一页)时,它应该被隐藏this.enableRefreshVibrate: false, // 刷新 开关this.enableLoadMoreVibrate: false,//加载  loadmore开关this.topHitBoundary,//边界位于上边缘,当惯性滚动超过边界距离时停止this.bottomHitBoundary,//边界位于底部边缘,当惯性在边界距离以下滚动时停止})

http://chatgpt.dhexx.cn/article/1tkHyEKa.shtml

相关文章

BaseQuickAdapter上拉加载功能实现

最近使用BaseQuickAdapter进行RecyclerView 的Adapter的数据绑定显示。 实现上拉加载与下拉刷新功能&#xff0c;遇到如下问题&#xff1a; 1、首先是实现下拉刷新、下拉加载的监听&#xff08;xml布局就不贴出来了&#xff09;&#xff1a; 2、现在贴出来错误的处理方式&…

android 官方上拉,手把手教你实现RecyclerView的下拉刷新和上拉加载更多

纵观多数App&#xff0c;下拉刷新和上拉加载更多是很常见的功能&#xff0c;但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新&#xff0c;上拉加载更多还要自己做。 基于RecyclerView简单封装了这两个操作&#xff0c;下拉刷新支持LinearLayoutManager、GridLayoutManager…

uniapp下拉刷新上拉加载

一、需求 留言板主页&#xff0c;显示所有的留言信息&#xff0c;带有分页功能&#xff1b;上拉加载数据&#xff0c;下拉刷新数据二、代码 1、pages.json 2、messageBoard.vue 用了 uniapp 提供的组件&#xff1a; uni-load-more.vue <uni-load-more :status"load…

jquery 实现上拉加载功能

emmmm&#xff0c;看到了以前自己的写的代码&#xff0c;用jquery实现的上拉加载&#xff0c;顺便修复了以前漏下的bug&#xff0c;感觉可以记录一波。 好的先上图&#xff0c; 好的首先关注console控制台&#xff0c;再来就是右图的内容&#xff0c;页面上初始仅有两个div 接…

微信小程序下拉刷新、上拉加载

微信小程序官方没有给出具体的下拉刷新和上拉加载组件&#xff0c;我们可以基于小程序原生组件scroll-view的扩展与封装,实现简单的上拉加载、下拉刷新组件。 1. 封装组件 // components/customPullDown/index.js Component({options: {multipleSlots: true},properties: {ch…

uniapp局部上拉加载数据

一、页面局部实现上拉加载数据 只有评论区可以上拉加载数据&#xff0c;网上找到了 vue-infinite-scroll二、使用 官方示例 1、 npm 加载依赖 npm install vue-infinite-scroll --save2、 单个页面引用 import infiniteScroll from vue-infinite-scrollexport default {dire…

【Compose】亲手封装一个简单灵活的下拉刷新上拉加载 Compose Layout

Compose 的下拉刷新有现成的 Material 库可以直接使用&#xff0c;非常简单方便。 但是上拉加载目前没看到有封装的特别好的库&#xff0c;Paging 有些场景无法满足&#xff0c;而且上拉加载也是个比较简单的功能&#xff0c;没必要再去依赖一个质量未知的库。我们可以基于目前…

如何实现上拉加载,下拉刷新?

如何实现上拉加载下拉刷新&#xff1f; 实现原理上拉加载下拉刷新 实现原理 上拉加载及下拉刷新都依赖于用户交互 最重要的是要理解在什么场景&#xff0c;什么时机下触发交互动作 上拉加载 首先可以看一张图 上拉加载的本质是页面触底&#xff0c;或者快要触底时的动作 判…

【前端知识之JS】如何实现上拉加载和下拉刷新

前言 本系列主要整理前端面试中需要掌握的知识点。本节介绍如何实现上拉加载和下拉刷新。 文章目录 前言一、介绍二、实现原理1、上拉加载2、下拉刷新 一、介绍 下拉刷新和上拉加载这两种交互方式通常出现在移动端中&#xff1b;本质上等同于PC网页中的分页&#xff0c;只是交…

大数据和人工智能到底是什么关系

大数据和人工智能的关系&#xff0c;首先要说什么是大数据。这些年来&#xff0c;大数据先是被神化&#xff0c;继而又被妖魔化&#xff0c;到了今天&#xff0c;其实谁也不知道别人所谓的大数据指的是什么。有时候大数据的定义里既有平台&#xff08;硬件&#xff09;又有分析…

大数据和人工智能AI的联系和区别

大数据和人工智能两个词是我们现在频繁听到的两个词汇&#xff0c;那么这两者之间到底有什么联系 首先我们要了解到什么是大数据&#xff1f;什么是人工智能&#xff1f;大数据就是一种规模大到在获取、存储、管理、分析方面大大超出了传统数据库软件工具能力范围的数据集合&…

人工智能、机器学习、深度学习 三者关系

目录 1、AI ML DL关系 2、发展历程 2.1、人工智能&#xff08;ArtificiaI Intelligence&#xff09; 2.2、机器学习&#xff08;Machine Learning&#xff09; 2.3、深度学习&#xff08;Deep Learning&#xff09; 1、AI ML DL关系 为了赋予计算机以人类的理解能力与逻辑…

云计算、大数据和人工智能三者到底什么关系

今天跟大家讲讲云计算、大数据和人工智能。为什么讲这三个东西呢&#xff1f;因为这三个东西现在非常火&#xff0c;并且它们之间好像互相有关系&#xff1a;一般谈云计算的时候会提到大数据、谈人工智能的时候会提大数据、谈人工智能的时候会提云计算……感觉三者之间相辅相成…

人工智能和大数据分析之间,主要有什么区别

首先来看看认知计算和人工智能的区别 人工智能的概念已经有二十多年&#xff0c;人工智能从历史和研究角度来讲主要目的是为了让机器表现的更像人类&#xff0c;我们称之为Intelligent Behavior。IBM的认知计算从技术角度上讲和AI是有很多共性的地方&#xff0c;比如机器学习&…

人工智能与大数据的完美结合

人工智能(AI)已经存在几十年了。然而&#xff0c;最近随着“大数据”的出现&#xff0c;它得到了越来越多的关注。维基百科对人工智能的释义如下: 在计算机科学中&#xff0c;人工智能研究的领域将自己定义为“智能代理AI和大数据&#xff1a;完美结合”的研究&#xff1a;任何…

大数据和人工智能的概念

大数据和人工智能的概念 概述大数据和人工智能领域的一些热门趋势。我们将看到世界如何通过数字化而改变&#xff0c;从而导致消费和工业领域的大数据现象&#xff1b;了解到数据量呈指数级增长&#xff0c;从太字节到艾字节再到泽字节&#xff1b;意识到计算机的处理能力增加…

云计算、大数据和人工智能之间的关系

大家好&#xff0c;这里是抖码课堂&#xff0c;抖码课堂专注提升互联网技术人的软硬实力。 这篇文章我们从下面的内容来聊下云计算、人工智能、大数据技术三者之间的关系 探讨什么是云计算&#xff0c;在这里分别探讨云计算的 IaaS、PaaS 以及 SaaS 探讨云计算和大数据技术之…

大数据属于人工智能吗?什么是大数据?

对于“大数据”(Big data)研究机构Gartner给出了这样的定义。“大数据”是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力来适应海量、高增长率和多样化的信息资产。大数据属于人工智能吗&#xff1f;本篇来解答一下这个问题。 大数据属于人工智能吗&#xff…

大数据和人工智能之间,主要有什么区别?

大数据vs.人工智能是一种公平的比较吗?在某种程度上&#xff0c;它是&#xff0c;但首先让我们先厘清它们之间的区别。 人工智能和大数据是人们耳熟能详的流行术语&#xff0c;但也可能会有一些混淆。人工智能和大数据有什么相似之处和不同之处?它们有什么共同点吗?它们是否…

AI和大数据的关系

近几年随着AlphaGO的骄人战绩&#xff0c;人工智能和大数据备受追捧&#xff0c;热度空前。而在实际接触中&#xff0c;大家对人工智能和大数据的认知普遍是“只知其名不知其意”&#xff0c;因此对企业而言&#xff0c;猎头的推荐也往往与岗位匹配度不高。那么被人们认为高深莫…