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

如何不依赖第三方包实现Flutter Bottom Sheet?

不依赖第三方包实现Flutter自定义Bottom Sheet组件

你可以直接用Flutter原生的showModalBottomSheet方法来实现符合需求的Bottom Sheet,完全不需要第三方包。下面是一个完整的可运行示例,包含圆角样式、自定义内容、拖拽关闭等常用功能:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('自定义Bottom Sheet示例')),
        body: Center(
          child: ElevatedButton(
            onPressed: () => _showCustomBottomSheet(context),
            child: const Text('打开Bottom Sheet'),
          ),
        ),
      ),
    );
  }

  void _showCustomBottomSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      // 设置顶部圆角
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      // 自定义背景色
      backgroundColor: Colors.white,
      // 阴影层级
      elevation: 8,
      // 允许点击外部关闭
      isDismissible: true,
      // 允许拖拽关闭
      enableDrag: true,
      builder: (BuildContext context) {
        return SizedBox(
          // 适配屏幕高度的一半
          height: MediaQuery.of(context).size.height * 0.5,
          child: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // 顶部拖拽指示器(可选,提升交互提示)
                  Center(
                    child: Container(
                      width: 40,
                      height: 4,
                      decoration: BoxDecoration(
                        color: Colors.grey[300],
                        borderRadius: BorderRadius.circular(2),
                      ),
                    ),
                  ),
                  const SizedBox(height: 20),
                  // 标题
                  const Text(
                    '选择操作',
                    style: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  const SizedBox(height: 16),
                  // 选项列表
                  ListTile(
                    leading: const Icon(Icons.share),
                    title: const Text('分享内容'),
                    onTap: () {
                      Navigator.pop(context);
                      // 这里添加分享逻辑
                    },
                  ),
                  ListTile(
                    leading: const Icon(Icons.copy),
                    title: const Text('复制链接'),
                    onTap: () {
                      Navigator.pop(context);
                      // 这里添加复制逻辑
                    },
                  ),
                  ListTile(
                    leading: const Icon(Icons.delete),
                    title: const Text('删除内容'),
                    textColor: Colors.red,
                    onTap: () {
                      Navigator.pop(context);
                      // 这里添加删除逻辑
                    },
                  ),
                  const SizedBox(height: 20),
                  // 底部取消按钮
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.blue,
                      ),
                      onPressed: () => Navigator.pop(context),
                      child: const Text('取消'),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

关键细节说明:

  • 圆角样式:通过shape属性传入RoundedRectangleBorder,自定义顶部圆角,让组件更贴合常见设计
  • 内容适配:用SingleChildScrollView包裹内容,避免内容过长时出现布局溢出错误
  • 高度控制:通过SizedBox的height属性自定义组件高度,结合MediaQuery可适配不同屏幕尺寸
  • 交互配置:isDismissible和enableDrag分别控制点击外部关闭、拖拽关闭的功能,可根据需求调整为false禁用
  • 半透明背景:如果需要半透明效果,只需将backgroundColor改为Colors.white.withOpacity(0.9)这类带透明度的颜色值即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:36:11