前言
由于flutter_easyrefresh有一点点的小bug,才做的此案例,对于一个项目而言,用户体验很重要
在哔哩哔哩中使用的上拉刷新跟这个是一样的
本案例是以一页数据可以请求20条
首先做一个上拉刷新,下拉加载,这两句话是什么意思
上拉刷新:,下拉的时候,将当前有限的屏幕中显示的数据替换当
这个提替换掉不是单纯的直接赋值掉,而是将数据插入在当前显示的列表当中
并且数据加载完毕之后提示用户
为什么要这么做?
试想一个场景,如果你将数据全部替换掉了,用户要看之前的浏览记录呢?
下拉下载:下拉的时候将数据加载到有限的屏幕显示
将请求的数据添加在末尾,没有数据了提示用户
不管是上拉刷新和下拉加载,都要判断是否为最后一页
需要的依赖
#网络请求
dio: any
#提示框
fluttertoast: ^8.0.4
代码
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class LoadDataPage extends StatefulWidget {
const LoadDataPage({Key? key}) : super(key: key);
@override
_LoadDataPageState createState() => _LoadDataPageState();
}
class _LoadDataPageState extends State<LoadDataPage> {
ScrollController _controller = new ScrollController();
//数据存放的容器
List data = [];
//当前请求数据的页数
int pageIndex = 1;
//是否是最后一页数据
bool isHasMore = true;
@override
void initState() {
dropDownLoad();
//监听长度的变化
_controller.addListener(() {
print("ListView长度滚动的距离" + _controller.position.pixels.toString());
print("ListView占屏幕的总距离" + _controller.position.maxScrollExtent.toString());
if (_controller.position.pixels > _controller.position.maxScrollExtent-40) {
setState(() {
pageIndex++;
dropDownLoad();
});
}
});
super.initState();
}
//请求数据
Future<List> requestData()async{
final api = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=${pageIndex}";
Response response = await Dio().get(api);
return json.decode(response.data)["result"];
}
// 下拉加载
Future dropDownLoad() async {
if (isHasMore) {
List list = await requestData();
//小于20条数据说明是最后一页了
if (list.length < 20) {
setState(() {
isHasMore = false;
data.addAll(list);
});
}else{
setState(() {
data.addAll(list);
});
}
print(data.toString() + "]]]]");
}
}
//上拉刷新
Future<void> _onRefresh()async{
await Future.delayed(Duration(seconds: 1), ()async{
pageIndex++;
List list = await requestData();
//如果请求到的数据是最后一页
if(list.length<20){
Fluttertoast.showToast(msg: "无再多的数据",gravity: ToastGravity.TOP);
}else{
data.insertAll(0, list);
setState(() {});
}
});
}
@override
Widget build(BuildContext context) {
final appAar = AppBar(
title: Text("使用flutter组件实现下拉刷新"),
);
return Scaffold(
appBar: appAar,
body: data.length > 0
? RefreshIndicator(
onRefresh:_onRefresh,
child: ListView.builder(
controller: _controller,
itemCount: data.length,
itemBuilder: (context, index) {
//如果是最后一条数据
print(data.length == index);
//data的length是0-19,index是1-20
if(this.data.length-1 == index){
print("到底了=====================================");
return Column(
children: [
ListTile(
subtitle: Text(data[index]["aid"]),
title: Text(data[index]["title"]),
),
Divider(),
_getMoreWidget(this.isHasMore),
],
);
}else{
return Column(
children: [
ListTile(
subtitle: Text(data[index]["aid"]),
title: Text(data[index]["title"]),
),
Divider(),
],
);
}
}),
)
: Center(child: CircularProgressIndicator()),
);
}
//加载到底部的圈圈
Widget _getMoreWidget(bool isData) {
if(isData){
return Center(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'加载中...',
style: TextStyle(fontSize: 16.0),
),
CircularProgressIndicator(
strokeWidth: 3.0,
color: Colors.pinkAccent,
)
],
),
),
);
}else{
return Center(child: Text("数据到底了"));
}
}
}