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

Flutter:实现带固定拖动触发区的可拖动底部表单问题

解决DraggableScrollableSheet固定头部的滚动问题

需求与当前问题

  • 需求:底部表单初始仅显示顶部白色触发条,向上拖动展开至最大高度(屏幕高度的80%)后,触发条和标题栏固定,仅下方列表可滚动
  • 当前问题:表单拉到最大高度时,滚动标题区域会带动整个sheet滚动,不符合预期

问题原因

原代码将整个内容包裹在SingleChildScrollView中,并把同一个scrollController同时绑定给外层滚动组件和内部ListView,导致头部区域的滚动事件被外层组件捕获,进而带动整个sheet移动。

修改后的代码

DraggableScrollableSheet(
  initialChildSize: 0.05,
  minChildSize: 0.05,
  maxChildSize: 0.8,
  builder: (BuildContext context, ScrollController scrollController) {
    return Container(
      margin: const EdgeInsets.only(top: 10),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        color: Colors.blueGrey,
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.5),
            spreadRadius: 2,
            blurRadius: 7,
            offset: const Offset(0, 3),
          ),
        ],
      ),
      padding: const EdgeInsets.symmetric(horizontal: 15),
      child: Column(
        children: <Widget>[
          // 顶部触发条
          SizedBox(
            height: 20,
            child: Center(
              child: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  color: Colors.white,
                ),
                width: 70,
                height: 7,
              ),
            ),
          ),
          // 标题栏
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              const Text('My cars'),
              IconButton(
                color: Colors.black,
                focusColor: Colors.red,
                splashRadius: 20,
                onPressed: () {},
                icon: const Icon(
                  CupertinoIcons.add,
                  size: 15,
                ),
              )
            ],
          ),
          // 可滚动列表
          Expanded(
            child: ListView.builder(
              controller: scrollController,
              itemCount: 25,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(title: Text('Item $index'));
              },
            ),
          ),
        ],
      ),
    );
  },
)

关键修改点

  • 移除外层SingleChildScrollView,消除滚动事件冲突
  • 将触发条和标题栏设为Column的固定子项,始终保持在顶部
  • 仅将DraggableScrollableSheet提供的scrollController绑定到内部ListView,确保sheet到达最大高度后,只有列表区域响应滚动操作
  • 用margin替代原顶部padding,避免多余间距影响布局

内容的提问来源于stack exchange,提问作者Michel Gisenaël

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:27:04