Flutter Dio请求列表+上拉刷新+下拉加载
2019-12-20 本文已影响0人
坤哥爱卿
1.数据请求
数据请求我这边用的是Dio库,支持Restful接口。
代码如下:
var dioUrl =
'http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=${this._page}';
Response response = await Dio().get(dioUrl);
var arr = json.decode(response.data)['result'];
print(arr);
列表展示用的是ListView.builder()
代码如下
ListView.builder(
itemCount: this._list.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${this._list[index]['title']}'),
);
})
2.下拉刷新
下拉刷新就是在ListView外面套一层RefreshIndicator,然后在其中的onRefresh方法中实现下拉刷新的功能

代码如下
注意:onRefresh是Future类型
//下拉刷新
Future<void> _onRefresh() async {
await Future.delayed(Duration(milliseconds: 1000), () {
print('请求数据完成');
this._page = 1;
_getListData();
});
}
3.加载更多
加载更多就是在ListView的controller属性中传入一个_scrollController类型为ScrollController,_scrollController可以获取滚动条下拉的距离和获取整个页面的高度,以此来判断是否滑动到最底部了(距离底部一定距离就开始刷新效果比较好,所以代码中减了40)
ScrollController _scrollController = new ScrollController();
//监听滑动
_scrollController.addListener(() {
//获取滚动条下拉的距离
print(_scrollController.position.pixels);
//获取整个页面的高度
print(_scrollController.position.maxScrollExtent);
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - 40) {
//开始加载更多
this._getListData();
}
});

完整代码如下
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class DioRequestResultPage extends StatefulWidget {
DioRequestResultPage({Key key}) : super(key: key);
@override
_DioRequestResultPageState createState() => _DioRequestResultPageState();
}
class _DioRequestResultPageState extends State<DioRequestResultPage> {
List _list = [];
int _page = 1;
bool hasMore = true; //判断有没有数据
ScrollController _scrollController = new ScrollController();
@override
void initState() {
// TODO: implement initState
super.initState();
this._getListData();
//监听滑动
_scrollController.addListener(() {
//获取滚动条下拉的距离
print(_scrollController.position.pixels);
//获取整个页面的高度
print(_scrollController.position.maxScrollExtent);
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - 40) {
//开始加载更多
this._getListData();
}
});
}
void _getListData() async {
if (this.hasMore) {
var dioUrl =
'http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=${this._page}';
Response response = await Dio().get(dioUrl);
var arr = json.decode(response.data)['result'];
print(arr);
setState(() {
if (this._page == 1) {
this._list = arr;
} else {
this._list.addAll(arr);
}
this._page++;
});
//判断是否为最后一页
if (arr.length < 20) {
setState(() {
this.hasMore = false;
});
}
}
}
//下拉刷新
Future<void> _onRefresh() async {
await Future.delayed(Duration(milliseconds: 1000), () {
print('请求数据完成');
this._page = 1;
_getListData();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dio Get请求渲染数据demo'),
),
body: this._list.length > 0
? RefreshIndicator(
onRefresh: _onRefresh,
child: ListView.builder(
controller: _scrollController,
itemCount: this._list.length,
itemBuilder: (context, index) {
//列表渲染到最后一条的时候加一个圈圈
if (index == this._list.length - 1) {
//拉到底
return Column(
children: <Widget>[
ListTile(
title: Text('${this._list[index]['title']}', maxLines: 1),
),
Divider(),
_getMoreWidget()
],
);
}
else {
return Column(
children: <Widget>[
ListTile(
title: Text('${this._list[index]['title']}', maxLines: 1),
),
Divider()
],
);
}
},
),
)
: Text('加载中...'),
);
}
//加载中的圈圈
Widget _getMoreWidget() {
if (hasMore) {
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: 1.0,
)
],
),
),
);
} else {
return Center(
child: Text("--我是有底线的--"),
);
}
}
}