You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 09:06:10