Flutter中使用ListView时常常会用到上拉刷新和下拉加载功能,上拉刷新比较好实现,直接在ListView外面套一层RefreshIndicator,再实现RefreshIndicator就可以了。下拉加载就没有现成的可以用了,需要我们自己来实现。本文主要对Flutter中上拉刷新和下拉加载功能封装为一个简单的类RefreshListView。
主要可以分为三个步骤来实现:
1.上拉刷新,如前面所说用RefreshIndicator来实现 ;
2.下拉加载,通过ScrollController监听是否滑动到底部,在滑到底部时添加自定义的动画效果;
3.没有更多数据的提示,也主要通过监听滑到底部时,检查是否有更多数据,没有则显示自定义的提示信息
下面我们结合代码来进行初步实现
上拉刷新
RefreshIndicator refreshIndicator = RefreshIndicator(
onRefresh: () => onRefresh(),
child: listView,
);
实现RefreshIndicator中的onRefresh方法,这里我们自定义了一个onRefresh()接口,外层调用时通过此方法进行数据的更新。child为一个listView,如下:
ListView listView = ListView.builder(
controller: scrollController,
itemCount: length + 1,
shrinkWrap: true,
itemBuilder: (context, index) {
return _generateItem(context, index);
}
);
下拉加载
ScrollController scrollController = ScrollController();
scrollController.addListener(() {
if(scrollController.position.pixels == scrollController.position.maxScrollExtent) {
print('arrive end: hasMore = $hasMore');
if(hasMore) {
onLoad();
}
}
});
在listView上添加一个scrollController,然后添加一个滑动监听,当listView滑动到底部时,这里有一个hasMore变量来判断是否还有更多数据,如果还有就加载更多。其中加载跟多的方法onLoad也是一个可供外层调用的接口。
没有更多数据的提示
Widget _generateItem(BuildContext context, int index) {
if(index < length) {
return buildItem(index);
} else {
if(hasMore) {
return _buildLoadMoreView();
} else {
return _buildNoMoreView();
}
}
}
在设置listView的itemCount时,我们设置的值为list的length加1,为的就是当listView滑到底部时显示更多数据的动画或者没有数据的提示。当hasMore为false时,就显示所有数据加载完成的提示信息。_buildNoMoreView代码如下:
Widget _buildNoMoreView() {
Container container = Container(
height: 40,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'- ',
style: TextStyle(
fontSize: Appearance.fontSize.title2,
color: Appearance.color.foot
),
),
Text(
'我也是有底线的',
style: TextStyle(
fontSize: Appearance.fontSize.title2,
color: Appearance.color.foot
),
),
Text(
' -',
style: TextStyle(
fontSize: Appearance.fontSize.title2,
color: Appearance.color.foot
),
),
],
)
),
);
return container;
}
这里只是象征性地给出了一种示例,你也可以自定义自己想要的提示信息显示效果。
最后,完整代码如下:
import 'package:flutter/material.dart';
import 'package:inee_flutter/profiles/appearance.dart';
typedef LoadMore = void Function();
typedef Refresh = Future Function();
typedef BuildItem = Widget Function(int);
class RefreshListView extends StatelessWidget {
final int length;
final LoadMore onLoad;
final Refresh onRefresh;
final BuildItem buildItem;
final bool hasMore;
RefreshListView({
Key key,
this.length,
this.onLoad,
this.onRefresh,
this.buildItem,
this.hasMore = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
if(length == 0) {
return Container();
}
ScrollController scrollController = ScrollController();
scrollController.addListener(() {
if(scrollController.position.pixels == scrollController.position.maxScrollExtent) {
print('arrive end: hasMore = $hasMore');
if(hasMore) {
onLoad();
}
}
});
ListView listView = ListView.builder(
controller: scrollController,
itemCount: length + 1,
shrinkWrap: true,
itemBuilder: (context, index) {
return _generateItem(context, index);
}
);
RefreshIndicator refreshIndicator = RefreshIndicator(
onRefresh: () => onRefresh(),
child: listView,
);
return refreshIndicator;
}
Widget _generateItem(BuildContext context, int index) {
if(index < length) {
return buildItem(index);
} else {
if(hasMore) {
return _buildLoadMoreView();
} else {
return _buildNoMoreView();
}
}
}
Widget _buildLoadMoreView() {
Container container = Container(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Center(
child: Image.asset("assets/loadingAnimation.gif", width: 29, height: 38),
),
),
);
return container;
}
Widget _buildNoMoreView() {
Container container = Container(
height: 40,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'- ',
style: TextStyle(
fontSize: Appearance.fontSize.title2,
color: Appearance.color.foot
),
),
Text(
'我也是有底线的',
style: TextStyle(
fontSize: Appearance.fontSize.title2,
color: Appearance.color.foot
),
),
Text(
' -',
style: TextStyle(
fontSize: Appearance.fontSize.title2,
color: Appearance.color.foot
),
),
],
)
),
);
return container;
}
}
网友评论