【开源鸿蒙跨平台开发先锋训练营】Day4~6 实现上拉加载下拉刷新能力
介绍了为解决接口数据不足问题而采用的新接口设计方案,该接口支持分页查询水果信息,包含页码、每页数量和水果类别三个参数。详细说明了接口返回的数据结构,包括水果基本属性、营养成分和功效等信息。重点阐述了在鸿蒙手机上使用Flutter实现下拉刷新和上拉加载功能的代码实现,通过RefreshIndicator组件和分页逻辑控制数据加载,当刷新时重置页码并替换列表,加载更多时追加数据。
前提
由于第三天的接口只有4条无法显示上拉加载和下拉刷新的功能,于是重新用另外一个接口来请求。
先说一下最新的接口设计
传参有三个字段 分别为page当前页,pageSize每页数量,category水果类别。query方式
返回参数格式为
{ "success": true, "data": { "list": [ { "chinese": "脐橙", "name": "脐橙", "english": "NavelOrange", "nutrition": [ [ "维生素C", "53mg/100g" ], [ "膳食纤维", "2.4g/100g" ], [ "钾", "159mg/100g" ], [ "叶酸", "40μg/100g" ], [ "热量", "47kcal/100g" ] ], "category": "时令水果", "colorImageUrl": "xxx", "transparentImageUrl": "", "benefits": "富含维生素C,增强免疫力,促进胶原蛋白合成,抗氧化,预防感冒", "detailImages": [], "detailDescription": "脐橙口感酸甜多汁,富含维生素C,可增强免疫力和抗氧化,适合日常食用。", "mainColor": "#FF9800", "mainBg": "#FBE185", "features": [ { "short": "增强免疫", "long": "富含维生素C,有助于增强身体免疫力。" }, { "short": "抗氧化", "long": "丰富的抗氧化物质,有效对抗自由基,延缓衰老。" } ] } ], "pagination": { "page": 1, "pageSize": 1, "total": 29, "totalPages": 29 } }, "message": null, "statusCode": 200 }
1.鸿蒙手机上上拉加载效果图片

使用 Flutter 的 RefreshIndicator 组件
Flutter 提供了内置的
RefreshIndicator组件来实现下拉刷新功能。这个组件会包裹一个可滚动的子组件(如 ListView、GridView 等),当用户在列表顶部向下拉动时,会显示一个圆形的加载指示器,同时触发onRefresh回调函数。工作流程:
用户手指在屏幕上向下滑动
当滑动距离超过阈值时,显示刷新指示器
用户松开手指,触发
onRefresh回调执行异步数据请求
请求完成后,刷新指示器自动收起
列表显示最新数据
RefreshIndicator(
onRefresh: () => _fetchData(isRefresh: true), // 下拉触发的回调
child: ListView.builder(
itemCount: _fruitList.length,
itemBuilder: (context, index) {
return FruitCard(fruit: _fruitList[index]);
},
),
)
下拉刷新实现
Future<void> _fetchData({bool isRefresh = false}) async {
if (isRefresh) {
_currentPage = 1; // 重置页码
_hasMore = true; // 重置加载更多状态
}
final result = await FruitApi.getFruitList(
page: _currentPage,
pageSize: _pageSize,
);
setState(() {
if (result != null) {
if (isRefresh) {
_fruitList = result.list; // 刷新:替换整个列表
} else {
_fruitList.addAll(result.list); // 加载更多:追加数据
}
}
});
}

2.上拉加载
Flutter 没有内置的上拉加载组件,需要我们通过
ScrollController来监听列表的滚动位置。当检测到用户滚动到列表底部时,自动触发加载更多数据的操作。步骤
创建
ScrollController并绑定到 ListView添加滚动监听器,监听滚动位置变化
当滚动位置等于最大滚动范围时,说明已到达底部
检查是否正在加载中、是否还有更多数据
如果满足条件,增加页码并请求下一页数据
将新数据追加到现有列表中
在列表底部显示加载指示器

定义变量
int _currentPage = 1; // 当前页码
final int _pageSize = 10; // 每页数量
bool _hasMore = true; // 是否还有更多数据
bool _loading = false; // 是否正在加载
final ScrollController _scrollController = ScrollController(); // 滚动控制器
初始化时添加滚动监听
@override
void initState() {
super.initState();
_scrollController.addListener(_onScroll);
}@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
监听滚动到底部
void _onScroll() {
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
if (!_loading && _hasMore) {
_loadMore();
}
}
}
加载更多数据
Future<void> _loadMore() async {
_currentPage++;
await _fetchData();
}Future<void> _fetchData({bool isRefresh = false}) async {
setState(() { _loading = true; });final result = await FruitApi.getFruitList(page: _currentPage, pageSize: _pageSize);
setState(() {
if (result != null) {
_fruitList.addAll(result.list); // 追加数据
_hasMore = result.list.length == _pageSize; // 判断是否还有更多
}
_loading = false;
});
}
列表绑定控制器并显示加载指示器
ListView.builder(
controller: _scrollController,
itemCount: _fruitList.length + (_hasMore ? 1 : 0),
itemBuilder: (context, index) {
if (index == _fruitList.length) {
return const Center(child: CircularProgressIndicator());
}
return FruitCard(fruit: _fruitList[index]);
},
)
3.最后
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)