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

能否为Flutter BottomSheet实现淡入淡出动画?若可行该如何操作?

Flutter BottomSheet 淡入淡出动画实现方案

当然可以在Flutter BottomSheet上实现淡入淡出动画,下面提供两种实用的实现方式:


方式一:利用showModalBottomSheet的过渡回调快速实现

通过showModalBottomSheet的transitionBuilder参数,直接替换默认的滑动过渡为淡入动画,代码简洁易上手:

void showFadingBottomSheet(BuildContext context) {
  showModalBottomSheet(
    context: context,
    backgroundColor: Colors.transparent, // 必须设为透明,避免默认背景干扰淡入效果
    transitionBuilder: (context, animation, secondaryAnimation, child) {
      return FadeTransition(
        // 绑定BottomSheet的入场动画控制器,实现从完全透明到不透明的过渡
        opacity: animation.drive(
          Tween<double>(begin: 0.0, end: 1.0).chain(
            CurveTween(curve: Curves.easeInOut), // 可选:添加缓动曲线让动画更自然
          ),
        ),
        child: child,
      );
    },
    builder: (context) {
      return Container(
        height: 200,
        decoration: const BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
        ),
        child: const Center(child: Text("带淡入动画的BottomSheet")),
      );
    },
  );
}

方式二:自定义可手动控制的淡入淡出BottomSheet

如果需要手动触发退出时的淡出动画(比如点击按钮关闭时播放淡出,而非默认的滑动退出),可以通过AnimationController实现完全可控的动画:

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

  @override
  State<FadingBottomSheet> createState() => _FadingBottomSheetState();
}

class _FadingBottomSheetState extends State<FadingBottomSheet> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _fadeAnimation;

  @override
  void initState() {
    super.initState();
    // 初始化动画控制器,设置时长为300ms
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );
    // 定义透明度从0到1的动画曲线
    _fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
    );
    // 组件初始化时自动播放淡入动画
    _animationController.forward();
  }

  // 播放淡出动画,完成后关闭BottomSheet
  Future<void> _closeWithFade() async {
    await _animationController.reverse();
    if (mounted) Navigator.of(context).pop();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      opacity: _fadeAnimation,
      child: Container(
        height: 200,
        decoration: const BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text("可手动控制淡出的BottomSheet"),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _closeWithFade,
              child: const Text("关闭"),
            ),
          ],
        ),
      ),
    );
  }
}

// 调用自定义BottomSheet的方法
void showCustomFadingBottomSheet(BuildContext context) {
  showModalBottomSheet(
    context: context,
    backgroundColor: Colors.transparent,
    builder: (context) => const FadingBottomSheet(),
  );
}

注意事项

  • 两种方式都需要将showModalBottomSheet的backgroundColor设为透明,否则默认的白色背景会遮挡淡入效果
  • 可通过修改Duration调整动画时长,更换Curve改变动画的缓动节奏
  • 若需要同时实现滑动+淡入的组合动画,可在transitionBuilder中嵌套SlideTransition和FadeTransition

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:57:22