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

如何实现DraggableScrollableSheet拖动到底部时自动隐藏?

实现DraggableScrollableSheet拖动到底部时消失的解决方案

你当前的代码错误监听了内部ListView的滚动事件,而非DraggableScrollableSheet本身的拖动位置,导致无法实现拖动sheet到底部使其消失的需求。下面是修正后的完整实现方案:

关键修改点

  • 移除自定义的ScrollController,改用DraggableScrollableController监听sheet的拖动位置
  • 设置minChildSize: 0,允许sheet被拖动到完全隐藏的状态
  • 通过控制器的size属性判断sheet是否被拖到底部,触发隐藏逻辑

修正后的完整代码

class DetailAnimals extends StatefulWidget {
  final String imgAnimal;
  final String name;
  final String kategori;
  final String jenisMakanan;
  final String deskripsi;
  final String audio;
  const DetailAnimals(
      {super.key,
      required this.imgAnimal,
      required this.name,
      required this.deskripsi,
      required this.audio,
      required this.kategori,
      required this.jenisMakanan});

  @override
  State<DetailAnimals> createState() => _DetailAnimalsState();
}

class _DetailAnimalsState extends State<DetailAnimals> {
  bool showSheet = true; // 默认显示sheet
  late DraggableScrollableController _sheetController;

  @override
  void initState() {
    _sheetController = DraggableScrollableController();
    // 监听sheet的尺寸变化
    _sheetController.addListener(_onSheetSizeChanged);
    super.initState();
  }

  @override
  void dispose() {
    _sheetController.removeListener(_onSheetSizeChanged);
    _sheetController.dispose();
    super.dispose();
  }

  void _onSheetSizeChanged() {
    // 用0.01替代0避免精度判断问题
    if (_sheetController.size <= 0.01) {
      setState(() {
        showSheet = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFfab800),
      appBar: AppBar(
        elevation: 0,
        automaticallyImplyLeading: false,
        leading: IconButton(
            onPressed: () {
              Future.delayed(const Duration(milliseconds: 250), () {
                Get.back();
              });
            },
            icon: const Icon(Icons.arrow_back_ios)
                .animate(delay: const Duration(milliseconds: 250))
                .slideX(begin: -2, end: 0)),
      ),
      body: Stack(
        fit: StackFit.expand,
        children: [
          // 你的内容区域
          // 此处添加原代码中注释的内容组件
          if (showSheet)
            DraggableScrollableSheet(
              controller: _sheetController,
              initialChildSize: 0.9,
              minChildSize: 0, // 允许sheet完全隐藏
              maxChildSize: 1,
              builder: (context, scrollController) {
                return Container(
                  decoration: const BoxDecoration(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(30.0),
                      topRight: Radius.circular(30.0),
                    ),
                    color: Color(0xFF2e2e2e),
                  ),
                  child: ListView.builder(
                    itemCount: animalsList.length,
                    controller: scrollController, // 使用sheet提供的滚动控制器
                    itemBuilder: (context, index) {
                      return ListTile(
                        leading: Image.asset(
                          animalsList[index]['imagePath']!,
                          width: 50,
                          height: 50,
                        ),
                        title: Text(animalsList[index]['name']!),
                        subtitle: Text(animalsList[index]['deskripsi']!),
                      );
                    },
                  ),
                );
              },
            ),
        ],
      ),
    );
  }
}

核心逻辑解释

  • DraggableScrollableController:专门用于监听和控制DraggableScrollableSheet的位置,其size属性代表当前sheet占父容器的比例(范围0-1)
  • minChildSize: 0:这是实现sheet完全消失的前提,允许sheet被拖动到完全隐藏的位置
  • _onSheetSizeChanged:当sheet尺寸缩小到接近0时,触发状态更新隐藏sheet
  • 内部ListView使用sheet提供的scrollController:Flutter会自动处理内部滚动与sheet拖动的交互,避免冲突

内容的提问来源于stack exchange,提问作者Muhammad Dika Haryadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:17:10