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

Flutter中ListView.builder无法滚动问题求助

解决CustomScrollView中嵌套ListView.builder无法滚动的问题

你的问题核心是滚动容器嵌套导致的事件冲突:外层CustomScrollView已经接管了整个页面的滚动逻辑,内层ListView.builder的滚动事件被拦截,无法正常触发。以下是两种可行的解决方案,优先推荐第一种符合Flutter设计规范的实现方式。

方案一:用SliverList替代ListView.builder(最优解)

CustomScrollView的设计初衷就是组合各类Sliver组件(如SliverAppBar、SliverList等),所有组件共享同一滚动上下文,不会出现滚动冲突。直接将列表部分改为SliverList,和其他Sliver组件配合使用即可:

修改后的完整build代码:

class _DashboardScreenState extends State<DashboardScreen> {
  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      appBar: CustomAppBar(),
      body: CustomScrollView(
        physics: ClampingScrollPhysics(),
        slivers: <Widget>[
          _buildHeader(screenHeight),
          // 按钮区域
          SliverToBoxAdapter(
            child: Container(
              width: 100,
              height: 65,
              child: Padding(
                padding: const EdgeInsets.only(top: 20),
                child: ElevatedButton(
                  onPressed: () {},
                  child: Text(
                    'Add',
                    style: TextStyle(fontSize: 18),
                  ),
                  style: ElevatedButton.styleFrom(
                      shape: StadiumBorder(),
                      backgroundColor: Palette.primaryColor),
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(child: SizedBox(height: 10)),
          // 列表区域改用SliverList
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  margin: const EdgeInsets.symmetric(
                    vertical: 10.0,
                    horizontal: 20.0,
                  ),
                  padding: const EdgeInsets.all(10.0),
                  height: screenHeight * 0.15,
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      colors: [Color(0xFFAD9FE4), Palette.primaryColor],
                    ),
                    borderRadius: BorderRadius.circular(20.0),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: <Widget>[
                      Image.asset(
                        "assets/worker.png",
                        height: 80,
                        width: 80,
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Text(
                            'Somme: 50 €',
                            style: const TextStyle(
                              color: Colors.white,
                              fontSize: 18.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          SizedBox(height: screenHeight * 0.01),
                          Text(
                            'Date: 19 novembre 2022',
                            style: TextStyle(fontSize: 10, color: Colors.white),
                          ),
                          SizedBox(height: screenHeight * 0.01),
                          Text(
                            'Follow the instructions\nto do your own test.',
                            style: const TextStyle(
                              color: Colors.white,
                              fontSize: 16.0,
                            ),
                            maxLines: 2,
                          ),
                        ],
                      )
                    ],
                  ),
                );
              },
              childCount: 6,
            ),
          ),
        ],
      ),
    );
  }
}

方案二:禁用ListView自身滚动(兼容旧写法,不推荐)

如果一定要保留ListView.builder的结构,可以禁用它的滚动物理,让滚动事件透传到外层CustomScrollView,同时保留shrinkWrap: true让ListView自适应内容高度:

修改后的ListView.builder代码片段:

ListView.builder(
  scrollDirection: Axis.vertical,
  physics: const NeverScrollableScrollPhysics(), // 禁用自身滚动逻辑
  shrinkWrap: true,
  itemCount: 6,
  itemBuilder: ((BuildContext context, int index) {
    // 子项代码不变
  })
)

注意:这种方式性能不如SliverList,因为shrinkWrap: true需要遍历所有子项计算高度,而SliverList是按需加载的,适合大量数据场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:50:16