Flutter下拉刷新上拉加载的简单实现方式一

简介: Flutter下拉刷新上拉加载的简单实现方式一

方式一:RefreshIndicator+ListView实现
import 'package:flutter/material.dart';

class SimpleRefreshDemoPage extends StatefulWidget {
const SimpleRefreshDemoPage({super.key});

@override
State createState() {
return _SimpleRefreshDemoPage();
}
}

class _SimpleRefreshDemoPage extends State {
final int pageSize = 50;

bool disposed = false;

List dataList = [];

final ScrollController _scrollController = ScrollController();

final GlobalKey refreshKey = GlobalKey();

Future onRefresh() async {
await Future.delayed(const Duration(seconds: 4));
dataList.clear();
for (int i = 0; i < pageSize; i++) {
dataList.add("refresh");
}

if (disposed) {
  return;
}
setState(() {});

}

Future loadMore() async {
await Future.delayed(const Duration(seconds: 4));
for (int i = 0; i < pageSize; i++) {
dataList.add("loadmore");
}
if (disposed) {
return;
}
setState(() {});
}

@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
loadMore();
}
});

Future.delayed(const Duration(seconds: 0), () {
  refreshKey.currentState?.show();
});

}

@override
void dispose() {
disposed = true;
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("SimpleRefreshDemoPage"),
),
body: RefreshIndicator(
key: refreshKey,
onRefresh: onRefresh,
child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, 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"),
),
);
},
itemCount: (dataList.length >= pageSize)
? dataList.length + 1
: dataList.length,
controller: _scrollController,
),
),
);
}
}
如何实现下拉刷新
RefreshIndicator
RefreshIndicator 是 Flutter 中用于实现下拉刷新功能的一个组件。RefreshIndicator 包裹一个可滚动的子组件,如 ListViewGridView,当用户下拉到列表顶部时,会触发刷新操作。上面的例子中RefreshIndicator包裹在了ListView。

    `onRefresh` 是一个返回 `Future` 的异步函数,用于执行刷新操作。

    关键属性

onRefresh: 必须实现的回调函数,定义刷新时的操作。child: 需要包裹的可滚动子组件。color: 刷新指示器的进度条颜色。backgroundColor: 刷新指示器的背景色。displacement: 指示器开始显示时与顶部的距离。 如何实现下拉加载 ScrollController _scrollController.addListener(() { if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) { loadMore(); } }); 如何检测用户是否滚动到了ScrollView的底部? _scrollController.position.pixels == _scrollController.position.maxScrollExtent _scrollController.position.pixels :表示当前滚动的位置。

_scrollController.position.maxScrollExtent :表示可滚动区域的最大值。

上面两个值相等时,说明用户已经滚动到了底部。

bool disposed 字段作用
在上面的代码中,bool disposed 字段用于指示 State 对象是否已经被销毁。当 dispose 方法被调用时,disposed 被设置为 true。这个字段主要用于在异步操作完成后,确保不会调用已经被销毁的 State 对象的 setState 方法。

作用分析
1.防止在销毁后调用 setState
异步操作(如 Future.delayed)在完成后,可能会尝试调用 setState 来更新 UI。然而,如果在异步操作执行期间,用户已经导航离开了当前页面,导致 State 对象被销毁,那么调用 setState 就会抛出异常,因为 State 已经不再是活动的。
通过检查 disposed 字段,可以在调用 setState 前确认 State 是否仍然有效,从而避免在组件销毁后对其进行不必要的更新。
2.提高代码的稳健性:
这种模式是一种防御性编程的方法,确保应用程序在面对不确定的异步执行时仍然是稳定的。
@override
void dispose() {
disposed = true;
super.dispose();
}

Future onRefresh() async {
await Future.delayed(const Duration(seconds: 4));
dataList.clear();
for (int i = 0; i < pageSize; i++) {
dataList.add("refresh");
}

if (disposed) {
  return;
}
setState(() {});

}

Future loadMore() async {
await Future.delayed(const Duration(seconds: 4));
for (int i = 0; i < pageSize; i++) {
dataList.add("loadmore");
}
if (disposed) {
return;
}
setState(() {});
}

onRefreshloadMore 方法中,disposed 被用来检查 State 是否已经被销毁。如果 disposedtrue,则不再调用 setState,从而避免可能的异常。

3.总结

使用 disposed 字段可以有效地防止在组件销毁后进行不必要或有害的 UI 更新。这种模式特别适用于涉及异步操作的 Flutter 应用开发,确保代码在处理 State 生命周期时更加健壮。

相关文章
|
开发框架 前端开发 UED
【Flutter前端技术开发专栏】Flutter中的下拉刷新与上拉加载更多
【4月更文挑战第30天】在Flutter移动应用开发中,下拉刷新和上拉加载更多能提升用户体验和用户参与度。通过`RefreshIndicator`组件和`ScrollController`实现下拉刷新与上拉加载。`RefreshIndicator`包裹可滚动Widget,`ScrollController`监听滚动事件以判断是否到达底部。性能优化包括避免重复加载、使用防抖技术和异步加载数据。参考Flutter官方文档和相关教程可进一步学习。
785 0
【Flutter前端技术开发专栏】Flutter中的下拉刷新与上拉加载更多
|
前端开发
Flutter 之列表下拉刷新和上拉加载
在实际的 App 中,下拉刷新和上滑加载更多是非常常见的交互形式。在 Flutter 中,有 flutter_easyrefresh开源插件用于实现下拉刷新和上滑加载更多。本篇介绍了有状态组件和 flutter_easyrefresh 的基本应用,同时使用模拟的方式完成了异步数据加载。
867 0
Flutter 之列表下拉刷新和上拉加载
【Flutter】ListView 列表高级功能 ( ScrollController 上拉加载更多 )
【Flutter】ListView 列表高级功能 ( ScrollController 上拉加载更多 )
728 0
【Flutter】ListView 列表高级功能 ( ScrollController 上拉加载更多 )
【Flutter】ListView 列表高级功能 ( RefreshIndicator 下拉刷新组件 )
【Flutter】ListView 列表高级功能 ( RefreshIndicator 下拉刷新组件 )
538 0
【Flutter】ListView 列表高级功能 ( RefreshIndicator 下拉刷新组件 )
|
数据处理 容器 Dart
Flutter 17: 图解 ListView 下拉刷新与上拉加载 (一)【flutter_refresh】
0 基础学习 Flutter,第十七步:ListView 上拉加载更多与下拉刷新,解决方案一!
5875 0
|
9月前
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
flutter开发中Use ‘const’ with the constructor to improve performance. Try adding the ‘const’ keyword to the constructor invocation.报错如何解决-优雅草卓伊凡
126 1
|
8月前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
478 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
318 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
8月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
540 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
293 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈