flutter下拉刷新上拉加载的简单实现方式三

        使用 `CustomScrollView` 结合 `SliverList` 实现了一个支持下拉刷新和上拉加载更多功能的滚动列表,对下面代码进行解析学习。

import 'dart:math';import 'package:flutter/material.dart';import 'custom_pull/gsy_refresh_sliver.dart';
import 'package:flutter/cupertino.dart' as IOS;class NewMyRefreshDemoPage extends StatefulWidget {const NewMyRefreshDemoPage({super.key});@overrideState<StatefulWidget> createState() => _NewMyRefreshDemoState();
}class _NewMyRefreshDemoState extends State<NewMyRefreshDemoPage> {final GlobalKey<CupertinoSliverRefreshControlState> sliverRefreshKey =GlobalKey<CupertinoSliverRefreshControlState>();final int pageSize = 30;bool disposed = false;List<String> dataList = [];final ScrollController _scrollController = ScrollController();Future<void> onRefresh() async {await Future.delayed(const Duration(seconds: 2));dataList.clear();for (int i = 0; i < pageSize; i++) {dataList.add("refresh");}if (disposed) {return;}setState(() {});}Future<void> loadMore() async {await Future.delayed(const Duration(seconds: 2));for (int i = 0; i < pageSize; i++) {dataList.add("loadmore");}if (disposed) {return;}setState(() {});}@overridevoid didChangeDependencies() {Future.delayed(const Duration(milliseconds: 500), () {_scrollController.animateTo(-141,duration: const Duration(milliseconds: 600), curve: Curves.linear);return true;});}@overridevoid dispose() {disposed = true;super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("NewMyRefreshDemoPage"),),body: NotificationListener(onNotification: (ScrollNotification notification) {//通知 CupertinoSliverRefreshControl 当前的拖拽状态sliverRefreshKey.currentState?.notifyScrollNotification(notification);if (notification is ScrollEndNotification) {if (_scrollController.position.pixels > 0 &&_scrollController.position.pixels ==_scrollController.position.maxScrollExtent) {loadMore();}}return false;},child: CustomScrollView(controller: _scrollController,physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),slivers: <Widget>[CupertinoSliverRefreshControl(key: sliverRefreshKey,refreshIndicatorExtent: 100,refreshTriggerPullDistance: 140,onRefresh: onRefresh,builder: buildSimpleRefreshIndicator,),//列表SliverSafeArea(sliver: SliverList(delegate: SliverChildBuilderDelegate((BuildContext context, int index) {if (index == dataList.length) {return Container(margin: const EdgeInsets.all(10),child: const Align(child: CircularProgressIndicator(),),);}return Card(child: Container(height: 60,alignment: Alignment.centerLeft,child: Text("Item ${dataList[index]} $index"),),);},childCount: (dataList.length >= pageSize)? dataList.length + 1: dataList.length,),))],),),);}
}Widget buildSimpleRefreshIndicator(BuildContext context,RefreshIndicatorMode? refreshState,double pulledExtent,double refreshTriggerPullDistance,double refreshIndicatorExtent) {const Curve opacityCurve = Interval(0.4, 0.8, curve: Curves.easeInOut);return Align(alignment: Alignment.bottomCenter,child: Padding(padding: const EdgeInsets.only(bottom: 16.0),child: refreshState != RefreshIndicatorMode.refresh? Opacity(opacity: opacityCurve.transform(min(pulledExtent / refreshTriggerPullDistance, 1.0)),child: const Icon(IOS.CupertinoIcons.down_arrow,color: IOS.CupertinoColors.inactiveGray,size: 36.0,),): Opacity(opacity: opacityCurve.transform(min(pulledExtent / refreshIndicatorExtent, 1.0)),child: const IOS.CupertinoActivityIndicator(radius: 14.0),),),);
}

相关代码解析

NewMyRefreshDemoPage

这是一个 `StatefulWidget`,表示可以维护状态的组件。核心功能是提供一个支持刷新和加载更多的列表页面。

_NewMyRefreshDemoState

`State` 类的子类,负责管理 `NewMyRefreshDemoPage` 的状态。包含了 `dataList` 用于存储列表数据,以及控制滚动和刷新状态的逻辑。

相关状态管理

  • `sliverRefreshKey`:一个 `GlobalKey`,用于访问 `CupertinoSliverRefreshControl` 的状态。
  • `pageSize`:每次刷新或加载的项目数。
  • `disposed`:用于标识状态是否已被销毁,避免在组件卸载后进行状态更新。
  • `dataList`:存储列表项的数据。
  • `_scrollController`:用于控制滚动行为的 `ScrollController`。

相关方法

  • `onRefresh`:模拟网络请求,清空并重新填充列表数据。
  • `loadMore`:模拟网络请求,向列表追加更多数据。
  • `didChangeDependencies`:在组件依赖变化时调用,初始化时会在短暂延时后滚动到一个指定位置以触发下拉刷新。
  • `dispose`:在组件卸载时调用,标记状态为已销毁。

UI 构建相关

`build` 方法

Scaffold:页面的基础结构,包含一个 `AppBar` 和 `body`。

NotificationListener:监听滚动事件,用于通知刷新控件当前的拖拽状态,以及检测是否到达滚动底部以加载更多。

CustomScrollView:允许在同一滚动视图中使用多个 sliver 组件。

  • CupertinoSliverRefreshControl:提供下拉刷新功能。
  • SliverSafeArea & SliverList:用于在安全区域内展示列表项。

`buildSimpleRefreshIndicator` 方法

  • `refreshState`:当前刷新状态。
  • `pulledExtent`:拖动距离。
  • `refreshTriggerPullDistance`:触发刷新的拖动距离。
  • `refreshIndicatorExtent`:指示器的最大显示高度。

GlobalKey

final GlobalKey<CupertinoSliverRefreshControlState> sliverRefreshKey =GlobalKey<CupertinoSliverRefreshControlState>();

用于标识 `CupertinoSliverRefreshControl` 的全局键,允许在其他地方访问其状态。在 Flutter 中,`GlobalKey` 是一个强大的工具,用于唯一地标识和访问某个特定的组件实例。通过使用 `GlobalKey`,你可以在树的其他地方访问这个组件的状态或执行某些操作。

GlobalKey 是一个特殊的键,可以在 widget 树中唯一标识一个 widget。它允许访问与之关联的 widget 状态(`State` 对象),这在需要跨越 widget 树访问状态时非常有用。

CupertinoSliverRefreshControlState

这是 `CupertinoSliverRefreshControl` 的状态类。使用 `GlobalKey` 可以直接访问这个状态,进行一些状态更新或调用状态中的方法。

使用场景:

  • 访问刷新控件的状态:通过 `sliverRefreshKey.currentState`,你可以访问 `CupertinoSliverRefreshControl` 的状态对象。
  • 通知滚动状态:在 `NotificationListener` 中,使用 `sliverRefreshKey.currentState?.notifyScrollNotification(notification)` 来通知刷新控件当前的滚动状态。

CupertinoSliverRefreshControl

`CupertinoSliverRefreshControl` 是 Flutter 中一个用于实现 iOS 风格下拉刷新效果的组件。它通常用于 `CustomScrollView` 中,以提供流畅的下拉刷新体验,类似于 iOS 应用的原生行为。

主要特性

  • iOS 风格:以 iOS 的外观和行为为设计基础,提供原生般的用户体验。
  • 与 Sliver 兼容:设计用于与 `CustomScrollView` 和 sliver 系统一起使用,适合实现复杂的滚动布局。
  • 自动处理刷新逻辑:通过提供 `onRefresh` 回调,轻松实现数据刷新逻辑。

主要属性

refreshTriggerPullDistance

定义触发刷新操作所需的下拉距离(默认值为 100.0)。用户必须拉动至少此距离才能触发刷新。

refreshIndicatorExtent

刷新指示器的最大高度(默认值为 60.0)。指示器在用户继续下拉时可以扩展到的最大高度。

builder

自定义刷新指示器的外观。默认情况下,使用内置的 iOS 风格指示器,你可以提供一个自定义构建函数来改变其外观。

onRefresh

异步回调函数,当用户触发刷新操作时调用。通常用于执行异步操作(如网络请求)来更新数据。

注意

  • `CustomScrollView`:用于包裹 `CupertinoSliverRefreshControl` 和 `SliverList`,使得刷新控件可以与列表一起滚动。
  • `CupertinoSliverRefreshControl`:提供下拉刷新功能,`onRefresh` 回调用于定义刷新时的逻辑(如更新数据)。
  • 刷新逻辑:在 `_handleRefresh` 中模拟了一个网络请求,通过 `Future.delayed` 来延迟刷新操作。

buildSimpleRefreshIndicator

`buildSimpleRefreshIndicator` 是一个用于自定义刷新指示器外观的函数。它通常在实现下拉刷新功能时与 `CupertinoSliverRefreshControl` 一起使用。这个函数根据用户下拉的距离和当前的刷新状态来动态调整指示器的外观。

BuildContext context

Flutter 的上下文对象,用于获取主题、媒体查询等信息。在这个函数中没有被直接使用。

RefreshIndicatorMode? refreshState

刷新指示器的当前状态。可能的值包括:

  • `inactive`:未触发刷新。
  • `drag`:用户正在拖动,但未达到刷新阈值。
  • `armed`:用户拖动超过阈值,松手后将触发刷新。
  • `refresh`:正在刷新中。
  • `done`:刷新完成。

该函数使用此状态来决定显示箭头图标还是加载动画。

double pulledExtent

用户下拉的距离(以像素为单位)。

double refreshTriggerPullDistance

触发刷新的下拉距离阈值。

double refreshIndicatorExtent

刷新指示器的最大显示高度。

Curve

const Curve opacityCurve = Interval(0.4, 0.8, curve: Curves.easeInOut)

使用 `Interval` 定义一个曲线,用于控制不透明度变化的动画效果。`Interval(0.4, 0.8, curve: Curves.easeInOut)` 表示在 40% 到 80% 的时间内应用 `easeInOut` 曲线。

刷新指示器的作用

使用条件表达式根据 `refreshState` 的值显示不同的组件:

  • 如果状态不是 `RefreshIndicatorMode.refresh`,则显示一个箭头图标,且图标的透明度根据 `pulledExtent` 与 `refreshTriggerPullDistance` 的比例动态调整。
  • 如果状态是 `RefreshIndicatorMode.refresh`,则显示一个 `CupertinoActivityIndicator` 加载动画,且透明度根据 `pulledExtent` 与 `refreshIndicatorExtent` 的比例调整。

如何工作

  • 当用户开始下拉时,指示器的箭头图标会根据下拉距离逐渐显现。
  • 当用户的下拉距离超过 `refreshTriggerPullDistance` 并松手后,指示器状态变为 `refresh`,显示加载动画。
  • 加载动画的透明度也会随着用户下拉距离的变化而变化,提供更好的视觉反馈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/14699.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

hadoop报错找不到主类

错误&#xff1a; (base) mpsmps3:~$ hadoop hadoop_map_redce-1.0-SNAPSHOT.jar MovieDriver /input/movies-to-be-predicted.txt Error: Could not find or load main class hadoop_map_redce-1.0-SNAPSHOT.jar解决办法&#xff1a; 1.输入命令 hadoop classpath配置好了ha…

使用 start-local 脚本在本地运行 Elasticsearch

警告&#xff1a;请勿将这些说明用于生产部署 本页上的说明仅适用于本地开发。请勿将此配置用于生产部署&#xff0c;因为它不安全。请参阅部署选项以获取生产部署选项列表。 使用 start-local 脚本在 Docker 中快速设置 Elasticsearch 和 Kibana 以进行本地开发或测试。 此设…

Day14 - CV项目实战:SAR飞机检测识别

论文原文&#xff1a; ​​​​​​SAR-AIRcraft-1.0:高分辨率SAR飞机检测识别数据集 - 中国知网 第一排的7张图片&#xff0c;普通人肉眼很难看出对应的是第二排的飞机。 还有上图里标注的飞机&#xff0c;外行根本看不明白&#xff0c;为什么这些是&#xff0c;其他的不是。…

Threejs 材质贴图、光照和投影详解

1. 材质和贴图 材质&#xff08;Material&#xff09;定义了物体表面的外观&#xff0c;包括颜色、光泽度、透明度等。贴图&#xff08;Textures&#xff09;是应用于材质的图像&#xff0c;它们可以增加物体表面的细节和真实感。 1.1材质类型 MeshBasicMaterial&#xff1a…

笔记整理—linux驱动开发部分(11)中断上下文

触摸屏分为两种&#xff0c;一种为电阻式触摸屏&#xff0c;另一种为电容式触摸屏。电阻式触摸屏&#xff08;x、x-、y、y-、AD&#xff09;有两种接口&#xff0c;一种为SOC自带的接口&#xff08;miscinput或platform&#xff09;&#xff0c;第二种为外部IC&#xff0c;通过…

网络编程示例之开发板测试

编译elf1_cmd_net程序 &#xff08;一&#xff09;设置交叉编译环境。 &#xff08;二&#xff09;查看elf1_cmd_net文件夹Makefile文件。查看当前编译规则&#xff0c;net_demo是编译整个工程&#xff0c;clean是清除工程。 &#xff08;三&#xff09;输入命令。 &#xff0…

【GD32】(一) 开发方式简介及标准库开发入门

文章目录 0 前言1 开发方式选择2 标准库模板的创建3 遇到的问题和解决方法 0 前言 因为项目关系&#xff0c;需要使用GD32。之前对此早有耳闻&#xff0c;知道这个是一个STM32的替代品&#xff0c;据说甚至可以直接烧录STM32的程序&#xff08;一般是同型号&#xff09;&#x…

Java NIO 核心知识总结

NIO 简介 在传统的 Java I/O 模型&#xff08;BIO&#xff09;中&#xff0c;I/O 操作是以阻塞的方式进行的。也就是说&#xff0c;当一个线程执行一个 I/O 操作时&#xff0c;它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈&#xff0c;因为需…

Spring如何解决循环依赖的问题

Spring 如何解决循环依赖的问题 Spring 是通过三级缓存来解决循环依赖问题&#xff0c;第一级缓存里面存储完整的Bean实例&#xff0c;这些实例是可以直接被使用的&#xff0c;第二级缓存存储的是实例化后但是还没有设置属性值的Bean实例&#xff0c;也就是Bean里面的 依赖注入…

深度图变换器的新突破:DeepGraph

人工智能咨询培训老师叶梓 转载标明出处 在图变换器领域&#xff0c;尽管其全局注意力机制在图结构数据处理上显示出了巨大潜力&#xff0c;但现有的图变换器模型却普遍较浅&#xff0c;通常不超过12层。这一现象引发了学者们对于“增加层数是否能进一步提升图变换器性能”的深…

单体架构 IM 系统之 Server 节点状态化分析

基于 http 短轮询模式的单体架构的 IM 系统见下图&#xff0c;即客户端通过 http 周期性地轮询访问 server 实现消息的即时通讯&#xff0c;也就是我们前面提到的 “信箱模型”。“信箱模型” 虽然实现非常容易&#xff0c;但是消息的实时性不高。 我们在上一篇文章&#xff08…

阿里云通义大模型团队开源Qwen2.5-Coder:AI编程新纪元

&#x1f680; 11月12日&#xff0c;阿里云通义大模型团队宣布开源通义千问代码模型全系列&#xff0c;共6款Qwen2.5-Coder模型。这些模型在同等尺寸下均取得了业界最佳效果&#xff0c;其中32B尺寸的旗舰代码模型在十余项基准评测中均取得开源最佳成绩&#xff0c;成为全球最强…

计算机网络(8)数据链路层之子层

上一篇已经讲到数据链路层可以分为两个子层&#xff0c;这次将重点讲解子层的作用和ppp协议 数据链路层的子层 数据链路层通常被分为两个子层&#xff1a; 逻辑链路控制子层&#xff08;LLC&#xff0c;Logical Link Control&#xff09;&#xff1a; LLC子层负责在数据链路…

【操作系统】输入/输出(I/O)管理

王道笔记 一、I/O管理描述 1.1 I/O设备的概念和分类 1.1.1 什么是I/O设备 “I/O”就是“输入/输出”&#xff08;Input/Output&#xff09; I/O设备机会可以将数据输入到计算机&#xff0c;或者可以接收计算机输出数据的外部设备&#xff0c;属于计算机中的硬件部件。下图就…

Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV买卖股票的最佳时机III309.买卖股票的最佳时机含冷冻期

Day44 | 动态规划 &#xff1a;状态机DP 买卖股票的最佳时机IV&&买卖股票的最佳时机III&&309.买卖股票的最佳时机含冷冻期 动态规划应该如何学习&#xff1f;-CSDN博客 本次题解参考自灵神的做法&#xff0c;大家也多多支持灵神的题解 买卖股票的最佳时机【…

Koa进阶:掌握中间件和参数校验的艺术

目录 一、首先下载依赖 二、在index.js中引入koa-parameter&#xff0c;一般挂载这个中间件时会放在注册请求体的后面 三、使用实例 四、如果跟我们所需求的参数不同&#xff0c;返回结果直接会返回422 koa-parameter一般是用来校验请求传过来的参数是否是自己所需要的的 G…

opencv(c++)----图像的读取以及显示

opencv(c)----图像的读取以及显示 imread: 作用&#xff1a;读取图像文件并将其加载到 Mat 对象中。参数&#xff1a; 第一个参数是文件路径&#xff0c;可以是相对路径或绝对路径。第二个参数是读取标志&#xff0c;比如 IMREAD_COLOR 表示以彩色模式读取图像。 返回值&#x…

git config是做什么的?

git config是做什么的&#xff1f; git config作用配置级别三种配置级别的介绍及使用&#xff0c;配置文件说明 使用说明git confi查看参数 默认/不使用这个参数 情况下 Git 使用哪个配置等级&#xff1f; 一些常见的行为查看配置信息设置配置信息删除配置信息 一些常用的配置信…

【计算机网络】【传输层】【习题】

计算机网络-传输层-习题 文章目录 10. 图 5-29 给出了 TCP 连接建立的三次握手与连接释放的四次握手过程。根据 TCP 协议的工作原理&#xff0c;请填写图 5-29 中 ①~⑧ 位置的序号值。答案技巧 注&#xff1a;本文基于《计算机网络》&#xff08;第5版&#xff09;吴功宜、吴英…

【二叉搜素树】——LeetCode二叉树问题集锦:6个实用题目和解题思路

文章目录 计算布尔二叉树的值求根节点到叶节点的数字之和二叉树剪枝验证二叉搜索树二叉搜索树中第K小的元素二叉树的所有路径 计算布尔二叉树的值 解题思路&#xff1a; 这是一个二叉树的布尔评估问题。树的每个节点包含一个值&#xff0c;其中叶子节点值为 0 或 1&#xff0…