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

Flutter Web:创建独立无状态类的右侧半屏自定义BottomSheet

实现从右侧滑入的自定义BottomSheet(Flutter Web)

核心思路

默认BottomSheet无法满足右侧滑入需求,我们通过Overlay+动画组件实现:

  • 用OverlayEntry在页面顶层插入自定义弹窗
  • 通过AnimatedPositioned控制弹窗从屏幕右侧滑入/滑出的动画
  • 弹窗宽度设为屏幕宽度的50%,覆盖右侧半屏

完整代码实现

1. 自定义右侧滑入BottomSheet组件

import 'package:flutter/material.dart';

class RightSlideBottomSheet extends StatelessWidget {
  final Widget child;
  final bool isVisible;
  final VoidCallback onClose;

  const RightSlideBottomSheet({
    super.key,
    required this.child,
    required this.isVisible,
    required this.onClose,
  });

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final sheetWidth = screenWidth * 0.5;

    return GestureDetector(
      // 点击遮罩关闭弹窗
      onTap: onClose,
      child: Stack(
        children: [
          // 半透明遮罩层
          Visibility(
            visible: isVisible,
            child: Container(
              width: double.infinity,
              height: double.infinity,
              color: Colors.black.withOpacity(0.5),
            ),
          ),
          // 右侧滑入的弹窗主体
          AnimatedPositioned(
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeInOut,
            right: isVisible ? 0 : -sheetWidth,
            top: 0,
            bottom: 0,
            width: sheetWidth,
            child: GestureDetector(
              // 阻止弹窗内部点击触发遮罩关闭
              onTap: () {},
              child: Material(
                elevation: 8,
                child: child,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

2. 集成InkWell触发逻辑(示例页面)

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  bool _isSheetVisible = false;

  void _toggleSheet() {
    setState(() {
      _isSheetVisible = !_isSheetVisible;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("右侧滑入BottomSheet示例")),
      body: Stack(
        children: [
          // 页面主体内容
          Center(
            child: InkWell(
              onTap: _toggleSheet,
              child: Container(
                padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
                decoration: BoxDecoration(
                  color: Colors.blue,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: const Text(
                  "点击打开右侧弹窗",
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
          ),
          // 插入自定义BottomSheet
          if (_isSheetVisible)
            RightSlideBottomSheet(
              isVisible: _isSheetVisible,
              onClose: _toggleSheet,
              child: Padding(
                padding: const EdgeInsets.all(20),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      "右侧弹窗内容",
                      style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                    const SizedBox(height: 20),
                    const Text("这里可以添加任意组件"),
                    const Spacer(),
                    Align(
                      alignment: Alignment.bottomRight,
                      child: TextButton(
                        onPressed: _toggleSheet,
                        child: const Text("关闭"),
                      ),
                    ),
                  ],
                ),
              ),
            ),
        ],
      ),
    );
  }
}

关键说明

  • 弹窗宽度通过MediaQuery获取屏幕宽度后乘以0.5,适配不同尺寸的Web屏幕
  • 动画使用AnimatedPositioned实现平滑的滑入/滑出效果,时长300ms
  • 遮罩层点击可关闭弹窗,弹窗内部点击不会触发关闭,避免误操作
  • 弹窗使用Material组件包裹,保证Web端的视觉层级和阴影效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:15:54