使用GetX实现ListView无限滚动时滚动到底部触发列表重复重建问题排查
ListView 无限滚动加载异常问题
- 项目采用GetX做状态管理,通过后端API拉取分页数据,为ListView实现无限滚动加载能力
- 现存异常:每次滚动到列表末尾时,整个ListView都会触发不必要的重建,伴随重复拉取数据的问题,无法定位问题根源
- 预期效果:实现顺滑的列表懒加载滚动体验
现有实现代码
数据模型序列化逻辑
List<ExploreModel> exploreModelFromJson(String str) => List<ExploreModel>.from( json.decode(str).map((x) => ExploreModel.fromJson(x)).toList()); String exploreModelToJson(List<ExploreModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
GetX 业务控制器实现
class ExploreController extends GetxController { var isLoading = true.obs; var articleList = <ExploreModel>[].obs; var offsetCount = 0; @override void onInit() { fetchArticles(); super.onInit(); } void fetchArticles({int offsetCount = 0}) async { try { isLoading(true); var articles = await ApiService.fetchArticleList(offsetCount); if (articles != null) { articleList.addAll(articles); } } finally { isLoading(false); } } }
后端API请求封装
static Future<List<ExploreModel>> fetchArticleList(int offsetCount) async { var url = Uri.http(Config().baseUrl, Config().baseUrlPathGetArticles, {'offsetCount': '$offsetCount'}); var response = await http.get(url); if (response.statusCode == 200) { return exploreModelFromJson(utf8.decode(response.bodyBytes)); } else { return null; } }
页面视图层(StatefulWidget)实现
初始化阶段定义与监听逻辑
final ScrollController scrollController = ScrollController(); int offsetCount = 0; @override void initState() { super.initState(); scrollController.addListener(() { if (scrollController.position.pixels == scrollController.position.maxScrollExtent) { offsetCount = offsetCount + 5; exploreController.fetchArticles(offsetCount: offsetCount); } }); }
页面核心build结构
@override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: RefreshIndicator( key: _refreshIndicatorKey, onRefresh: () async { exploreController.fetchArticles(); }, child: Column( children: <Widget>[ Expanded( child: Obx(() { if (exploreController.isLoading.value) { return const CupertinoActivityIndicator(); } return ListView.separated( controller: scrollController, itemCount: exploreController.articleList.length, // 列表item渲染逻辑省略 ); }), ), ], ), ), ), ); }
内容的提问来源于stack exchange,提问作者jancooth
相关产品推荐
相关产品推荐

