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

Flutter:使用Future JSON数据填充SliverList时遇问题求助

解决用Future填充SliverFixedExtentList的问题

嘿,我来帮你搞定这个问题!你碰到的两个错误,其实都是Sliver组件使用时的常见误区,咱们一步步拆解修复:

问题根源分析

  1. 非Sliver组件直接塞进slivers列表:CustomScrollView的slivers数组只能放继承自RenderSliver的组件,你在else分支返回的Padding是普通Widget,直接放进去就触发了断言错误。
  2. Future传递方式错了:你把函数引用_getMyListOfCustomJsonObjects传给了future参数,而不是调用函数得到的Future对象——这会导致每次Widget重建都重新发起API请求,甚至引发重复GlobalKey的问题。
  3. 状态判断不够严谨:只靠snapshot.data != null判断状态会忽略加载中的阶段,应该结合connectionState来处理不同场景。

修正后的完整代码

class YourPage extends StatefulWidget {
  @override
  _YourPageState createState() => _YourPageState();
}

class _YourPageState extends State<YourPage> {
  // 提前在initState里初始化Future,避免重复请求
  late Future<List<CustomJsonObject>> _dataFuture;

  @override
  void initState() {
    super.initState();
    _dataFuture = _getMyListOfCustomJsonObjects();
  }

  Future<List<CustomJsonObject>> _getMyListOfCustomJsonObjects() {
    // 这里替换成你的实际API请求逻辑
    return Future.delayed(const Duration(seconds: 2), () {
      return [
        CustomJsonObject(Name: "Item 1"),
        CustomJsonObject(Name: "Item 2"),
        CustomJsonObject(Name: "Item 3"),
      ];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          const SliverAppBar(
            title: Text("Sliver List Demo"),
            pinned: true,
          ),
          FutureBuilder<List<CustomJsonObject>>(
            // 使用提前初始化的Future,避免重复请求
            future: _dataFuture,
            builder: (context, snapshot) {
              // 处理加载中状态
              if (snapshot.connectionState == ConnectionState.waiting) {
                return SliverToBoxAdapter(
                  child: Padding(
                    padding: const EdgeInsets.only(top: 50),
                    child: Stack(
                      alignment: Alignment.bottomCenter,
                      children: [
                        CircularProgressIndicator(
                          strokeWidth: 4,
                          backgroundColor: const Color(0xFFe5ac3b),
                          semanticsLabel: "Loading",
                          valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF12336c)),
                        ),
                      ],
                    ),
                  ),
                );
              } 
              // 处理错误状态
              else if (snapshot.hasError) {
                return SliverToBoxAdapter(
                  child: Center(child: Text("加载出错啦: ${snapshot.error}")),
                );
              } 
              // 数据加载完成且不为空
              else if (snapshot.hasData && snapshot.data!.isNotEmpty) {
                return SliverFixedExtentList(
                  itemExtent: 150,
                  delegate: SliverChildBuilderDelegate(
                    (context, index) {
                      final item = snapshot.data![index];
                      return Container(
                        color: Colors.red,
                        child: Center(child: Text(item.Name)),
                      );
                    },
                    childCount: snapshot.data!.length,
                  ),
                );
              } 
              // 空数据状态
              else {
                return const SliverToBoxAdapter(
                  child: Center(child: Text("暂无数据")),
                );
              }
            },
          ),
        ],
      ),
    );
  }
}

// 假设你的CustomJsonObject类是这样的
class CustomJsonObject {
  final String Name;
  CustomJsonObject({required this.Name});
}

关键修改点详解

  • 提前初始化Future:在initState里创建_dataFuture,确保API请求只执行一次,这不仅避免了重复请求,还解决了"Duplicate GlobalKeys"的错误。
  • 用SliverToBoxAdapter包裹普通Widget:所有非Sliver组件(比如加载指示器、空状态文本)都需要用SliverToBoxAdapter包裹,才能被CustomScrollView识别为合法的sliver子组件。
  • 完善状态处理:新增了加载中、错误、空数据的状态分支,让界面逻辑更完整,用户体验更好。
  • 指定FutureBuilder泛型:明确FutureBuilder<List<CustomJsonObject>>的泛型,让snapshot.data的类型更清晰,代码更安全。

这样修改后,你的SliverFixedExtentList就能正常用Future返回的数据填充,之前的两个错误也能彻底解决啦!

内容的提问来源于stack exchange,提问作者AustinT56

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:12:47