【flutter】避免FutureBuilder组件的多次刷新页面
最近碰到一个需求:页面有若干card,需要初始化请求数据,同时,该页面1.点击card组件有页面跳转和页面刷新数据的需求2.页面具有搜索栏,可以对card的标题进行搜索分析:【初始化请求数据】使用FutureBuilder组件即可完成需求,在future中定义请求数据函数即可,通过返回的snapshot组成返回的Widget刷新页面。【搜索栏】通过获取的搜索数据对card的标题进行字符串匹配,筛选
最近碰到一个需求:页面有若干card,需要初始化请求数据,同时,该页面
1.点击card组件有页面跳转和页面刷新数据的需求
2.页面具有搜索栏,可以对card的标题进行搜索
分析:
【初始化请求数据】使用FutureBuilder组件即可完成需求,在future中定义请求数据函数即可,通过返回的snapshot组成返回的Widget刷新页面。
【搜索栏】通过获取的搜索数据对card的标题进行字符串匹配,筛选出符合条件的card后,通过更新返回的Widget来完成页面的刷新。
问题:
每当点击card的时候,再次返回本页面,因为FutureBuilder组件内置了setState函数,都会出发future请求从而对页面进行一次刷新,如果没有搜索栏功能,这刚好满足刷新页面的需求,可以不做处理。
但是,当存在搜索栏,在完成card的筛选后,使用setState函数必然重新触发future请求,请求到所有的数据会对进行筛选的card进行覆盖,这样就无法实现搜索功能。
解决:
尝试使用AsyncMemoizer类,对请求进行管理。(FutureBuilder多次请求的原理是每次setState函数刷新,都会返回一个新的对象,如果可以对对象进行保存,就可以避免重复刷新)
AsyncMemoizer类存在runOnce方法,可以实现避免重复刷新的需求。
但是在使用runOnce方法后,需求一又无法满足了。
此时可以通过
Future initUnreadList(bool flag) async{
if(flag) {
return await msgGetNoticeList(Api.noticeUnreadList,Token: Api.token);
}
else {
return _memoizer.runOnce(() async {
return await msgGetNoticeList(Api.noticeUnreadList,Token: Api.token);
});
}
}
这种添加flag的方式进行解决。
在后续的尝试中发现,我们不能阻止future请求的调用,只能通过flag来判断是否对snapshot.data中回传的数据更新到Widget中,通过这种方式实现对是否刷新的自主控制。
反思:
这种编程方式过于的不优雅,flag编程是程序员的大忌,但是暂时没有想到更好的替代方法。
更多推荐
所有评论(0)