RefreshIndicator 是下拉刷新指示器, 包装一个可滚动widget
示例:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
var list = [];
int page = 0;
bool isLoading = false; // 是否正在请求新数据
bool showMore = false; // 是否显示底部加载中提示
bool offState = false; // 是否显示进入页面时的圆形进度条
ScrollController scrollController = ScrollController();
@override
void initState() {
super.initState();
// 监听滚动事件
scrollController.addListener(() {
// 是否滑动到了最底部: 当前位置为滚动的最大高度
if (scrollController.position.pixels ==
scrollController.position.maxScrollExtent) {
setState(() {
showMore = true;
});
getMoreData();
}
});
getListData();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("RefreshIndicator"),
),
body: Stack(
children: <Widget>[
RefreshIndicator(
child: ListView.builder(
controller: scrollController,
itemCount: list.length + 1,//列表长度+底部加载中提示
itemBuilder: choiceItemWidget,
),
onRefresh: _onRefresh,
),
Offstage(
offstage: offState,
child: Center(
child: CircularProgressIndicator(),
),
),
],
)
),
);
}
@override
void dispose() {
super.dispose();
// 手动停止滑动监听
scrollController.dispose();
}
// 加载列表行组件
Widget choiceItemWidget(BuildContext context, int position) {
if (position < list.length) {
return HomeListItem(position, list[position], (position) {
debugPrint("点击了第$position条");
});
} else if (showMore) {
return showMoreLoadingWidget();
} else {
return null;
}
}
// 加载更多提示组件
Widget showMoreLoadingWidget() {
return Container(
height: 50.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('加载中...', style: TextStyle(fontSize: 16.0),),
],
),
);
}
// 模拟进入页面获取数据
void getListData() async {
if (isLoading) {
return;
}
setState(() {
isLoading = true;
});
await Future.delayed(Duration(milliseconds: 300), () {
setState(() {
isLoading = false;
offState = true;
list = List.generate(20, (i) {
return ItemInfo("ListView的一行数据$i");
});
});
});
}
// 模拟到底部加载更多数据
void getMoreData() async {
if (isLoading) {
return;
}
setState(() {
isLoading = true;
page++;
});
await Future.delayed(Duration(milliseconds: 300), () {
setState(() {
isLoading = false;
showMore = false;
list.addAll(List.generate(3, (i) {
return ItemInfo("上拉添加 $page : $i");
}));
});
});
}
// 模拟下拉刷新
Future<void> _onRefresh() async {
if (isLoading) {
return;
}
setState(() {
isLoading = true;
page = 0;
});
await Future.delayed(Duration(milliseconds: 300), () {
setState(() {
isLoading = false;
List tempList = List.generate(3, (i) {
return ItemInfo("下拉添加 $page : $i");
});
tempList.addAll(list);
list = tempList;
});
});
}
}
class ItemInfo {
String title;
ItemInfo(this.title);
}
// 定义一个回调接口
typedef OnItemClickListener = void Function(int position);
// ignore: must_be_immutable
class HomeListItem extends StatelessWidget {
int position;
ItemInfo iteminfo;
OnItemClickListener listener;
HomeListItem(this.position, this.iteminfo, this.listener);
@override
Widget build(BuildContext context) {
var widget = Column(
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
iteminfo.title,
style: TextStyle(
fontSize: 15.0,
color: Color(0xff999999),
),
)
],
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
height: 50.0,
padding: EdgeInsets.only(left: 20.0),
),
// 分割线
Container(
height: 1.0,
color: Color.fromARGB(255, 230, 230, 230),
)
],
);
// InkWell点击的时候有水波纹效果
return InkWell(
onTap: () => listener(position),
child: widget
);
}
}
效果: