在Flutter中系统已经为我们提供了google material design的刷新功能 , 样式与原生Android一样.
我们可以使用RefreshIndicator组件来实现Flutter中的下拉刷新
使用方法:
import 'package:flutter/material.dart';
class PullToRefreshListViewPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return PullToRefreshListViewPageState();
}
}
class PullToRefreshListViewPageState extends State<PullToRefreshListViewPage> {
List<String> _dataSoure = new List();
ScrollController _scrollController;
int pageNum = 1;
bool isLoading = false; // 是否正在加载更多
@override
void initState() {
// TODO: implement onCreate
super.initState();
_dataSoure = List.generate(8, (i) => '初始数据${i + 1}');
_scrollController = ScrollController();
// 监听是否滚动到底部
_scrollController.addListener(() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent &&
pageNum < 5) {
// 滑动到了底部 执行上拉加载逻辑
_loadMore();
}
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_scrollController.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
color: Color(0xfff5f5f5),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 35, bottom: 10),
child: Text(
'下拉刷新上拉更多',
style: TextStyle(
fontSize: 17,
color: Color(0xff3c3c3c),
decoration: TextDecoration.none),
),
),
Expanded(
child: RefreshIndicator(
child: MediaQuery.removePadding(
removeTop: true,
context: context,
child: ListView.builder(
itemCount: _dataSoure.length + 1,
controller: _scrollController,
itemBuilder: (context, index) {
if (index < _dataSoure.length) {
return _itemWidget(index);
} else {
// 最后一项,显示加载更多布局
return _loadMoreItem(pageNum < 5 ? '加载中...' : '到底啦');
}
})),
onRefresh: _refresh,
),
)
],
),
);
}
Widget _itemWidget(int index) {
return Container(
margin: EdgeInsets.only(bottom: 6),
padding: EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 8),
color: Color(0xffffffff),
child: Row(
children: <Widget>[
Container(
alignment: Alignment.center,
width: 64,
height: 64,
child: ClipRRect(
borderRadius: BorderRadius.circular(4.0),
child: new FadeInImage.assetNetwork(
placeholder: 'assets/defaultImage.png',
image:
'https://wx1.sinaimg.cn/mw690/005uGqDJgy1gfc41hvjxlj323p23pkjl.jpg',
width: 64,
height: 64,
fit: BoxFit.cover,
),
),
),
Expanded(
child: Container(
margin: EdgeInsets.all(10),
child: Text(
_dataSoure[index],
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16,
color: Color(0xff808080),
decoration: TextDecoration.none),
),
))
],
),
);
}
/// 加载更多Item
Widget _loadMoreItem(String fontContent) {
return Center(
child: Padding(
padding: EdgeInsets.all(15.0),
child: Text(fontContent,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Color(0xff808080),
decoration: TextDecoration.none)),
),
);
}
/// 下拉刷新
Future<Null> _refresh() async {
// 延迟加载
await Future.delayed(Duration(seconds: 2), () {
setState(() {
List<String> _refreshData = List.generate(8, (i) => '下拉添加数据${i + 1}');
pageNum = 1;
_dataSoure.clear();
_dataSoure.addAll(_refreshData);
});
});
}
/// 上拉加载
Future<Null> _loadMore() async {
if (!isLoading) {
setState(() {
isLoading = true;
});
await Future.delayed(Duration(seconds: 2), () {
setState(() {
isLoading = false;
pageNum++;
List<String> _loadMoreData =
List.generate(5, (i) => '上拉添加数据${i + 1}');
_dataSoure.addAll(_loadMoreData);
});
});
}
}
}