之前用listView,items超过50个就非常卡,感觉就20fps。按照flutter标称大性能,不该如此呀,看代码:
Widget listView = ListView.builder(
itemCount: listItem.length,
itemBuilder: (BuildContext context, int index){
return Container(color: Colors.blue,height: index.isEven?200:250);
},
physics: const NeverScrollableScrollPhysics(),//本身不滚动,让外面的singlescrollview来滚动
shrinkWrap:true,//收缩,让外面的singlescrollview来滚动
);
//EasyRefresh里面包含一个SingleScrollview
var easyRefresh = EasyRefresh(
child: listView,
header:App.theme.refreshHeader,
footer: App.theme.refreshFooter,
onRefresh: () async{
pageNo = 1;
requestData();
},
onLoad: () async{
pageNo++;
requestData();
},
);
return Expanded(child:easyRefresh);
经过查阅资料,listview是懒加载机制,只绘制屏幕范围内的item,屏幕外的item全部销毁,这样哪怕items再多也不会卡,因为它只加载屏幕内的几个items。
我这里会卡,就是因为设置shrinkWrap:true后,listview就不再是懒加载,而是会加载上所有items,绘制出一个超长列表,以便外层singlescrollview可以进行滚动,这样就会很卡。
解决:
既然找出问题了,那我们就解决,去掉shrinkWrap:true和physics: const NeverScrollableScrollPhysics()就行了,但是去掉之后就会和外层singlescrollview冲突,我们又需要EasyRefresh的刷新和上拉加载更多,我只好自己实现了。
刷新用RefreshIndicator,加载更多用scrollController.addListener,我们可以自己包装一下ListView
自定义的RefreshLoad类
class RefreshLoad{
static Widget buildListView(BuildContext context,{required int itemCount,required Widget Function(BuildContext, int) itemBuilder,Future<void> Function()? onRefresh,Future<void> Function()? onLoadMore}){
ScrollController scrollController = ScrollController();
if(onLoadMore!=null){
scrollController.addListener(() {
//print('pixels=${scrollController.position.pixels}');
if (scrollController.position.pixels == scrollController.position.maxScrollExtent) {
print('load more');
onLoadMore();
Future.delayed(Duration(seconds: 5),(){ // 延迟5s完成刷新
});
}
});
}
Widget listView = ListView.builder(
itemCount: onLoadMore==null?itemCount:itemCount+1,
itemBuilder: (BuildContext context,int index){
//加载更多
if(onLoadMore!=null && index == itemCount){
return Container(child: Text('加载更多'),alignment: Alignment.center,height: 40.w,);
}else{
return itemBuilder(context,index);
}
},
controller: scrollController,
);
listView = MediaQuery.removePadding(child:listView,context:context,removeTop: true,removeBottom: true);
return
onRefresh==null?listView:
RefreshIndicator(
onRefresh: onRefresh,//下拉刷新回调
displacement: 10.w, //指示器显示时距顶部位置
color: Colors.white, //指示器颜色,默认ThemeData.accentColor
backgroundColor: Colors.grey[300],//指示器背景颜色,默认ThemeData.canvasColor
//notificationPredicate: defaultScrollNotificationPredicate, //是否应处理滚动通知的检查(是否通知下拉刷新动作)
child: listView
);
}
}
调用
Widget listView = RefreshLoad.buildListView(
context,
itemCount: listItem.length,
itemBuilder: (BuildContext context, int index){
return Container(color: Colors.blue,height: index.isEven?200:250);
},
onRefresh: () async{
pageNo = 1;
requestData();
},
onLoadMore: () async{
pageNo++;
requestData();
}
);
网友评论