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

Flutter中如何实现点击按钮后从底部上浮的页面转场?

实现Flutter页面从底部向上浮起的效果

你要的这种从底部浮起覆盖整个页面的效果,确实和showModalBottomSheet这类弹窗组件不一样——后者是在当前页面之上弹出底部面板,而你需要的是页面级过渡动画或当前页面内全屏组件的滑入效果,下面给你两种针对性实现方案:


方案一:自定义页面路由(页面跳转场景)

如果是点击按钮跳转到新页面时需要这个浮起效果,可以自定义PageRoute替换系统默认路由过渡:

class SlideUpRoute extends PageRouteBuilder {
  final Widget page;

  SlideUpRoute({required this.page})
      : super(
          pageBuilder: (context, animation, secondaryAnimation) => page,
          transitionDuration: const Duration(milliseconds: 300),
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            // 从底部向上滑动的位移动画
            final slideTween = Tween<Offset>(
              begin: const Offset(0, 1),
              end: Offset.zero,
            ).animate(CurvedAnimation(
              parent: animation,
              curve: Curves.easeOutCubic,
            ));
            
            // 配合透明度动画增强浮起质感
            final fadeTween = Tween<double>(
              begin: 0.6,
              end: 1.0,
            ).animate(animation);

            return FadeTransition(
              opacity: fadeTween,
              child: SlideTransition(
                position: slideTween,
                child: child,
              ),
            );
          },
        );
}

使用时直接通过这个路由跳转:

ElevatedButton(
  onPressed: () {
    Navigator.push(
      context,
      SlideUpRoute(page: const TargetPage()),
    );
  },
  child: const Text('打开浮起页面'),
)

方案二:Stack + AnimatedContainer(当前页面内浮起场景)

如果不需要跳转页面,只是在当前页面内让全屏组件从底部浮起,用Stack嵌套AnimatedContainer就能实现:

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _isPanelVisible = false;

  @override
  Widget build(BuildContext context) {
    final screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      body: Stack(
        children: [
          // 原页面内容
          Center(
            child: ElevatedButton(
              onPressed: () {
                setState(() {
                  _isPanelVisible = !_isPanelVisible;
                });
              },
              child: const Text('触发浮起效果'),
            ),
          ),
          // 浮起的全屏面板
          AnimatedContainer(
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeOutCubic,
            transform: Matrix4.translationValues(
              0,
              _isPanelVisible ? 0 : screenHeight,
              0,
            ),
            child: Container(
              width: double.infinity,
              height: double.infinity,
              color: Colors.white,
              child: const Center(
                child: Text('浮起的页面内容'),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

两种方案核心都是通过动画控制位置:从屏幕底部(Offset(0,1)或screenHeight)过渡到屏幕顶部,配合Curves.easeOutCubic这类缓动曲线,能让动画更接近你要的自然浮起效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:25:06