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

如何用Flutter实现带下拉抽屉动画的Widget显示/隐藏效果?

可以用Flutter实现该显示/隐藏动效

你展示的是从右侧滑入+渐显的显示动效,以及反向的滑出+渐隐隐藏动效,Flutter完全可以实现,下面是两种常用的实现方式:

方案1:使用AnimatedContainer + Opacity(快速实现)

这种方式无需额外的动画控制器,通过状态切换即可驱动动画:

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

  @override
  State<SlideToggleWidget> createState() => _SlideToggleWidgetState();
}

class _SlideToggleWidgetState extends State<SlideToggleWidget> {
  bool _isVisible = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: () => setState(() => _isVisible = !_isVisible),
            child: Text(_isVisible ? '隐藏' : '显示'),
          ),
          const SizedBox(height: 20),
          AnimatedContainer(
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeInOut,
            width: _isVisible ? 200 : 0,
            child: Opacity(
              opacity: _isVisible ? 1 : 0,
              child: Container(
                height: 100,
                color: Colors.blue,
                alignment: Alignment.center,
                child: const Text('目标内容', style: TextStyle(color: Colors.white)),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

方案2:使用SlideTransition + FadeTransition(灵活可控)

如果需要更精细的动画控制(比如自定义曲线、动画序列),可以结合动画控制器实现:

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

  @override
  State<CustomSlideToggle> createState() => _CustomSlideToggleState();
}

class _CustomSlideToggleState extends State<CustomSlideToggle> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Offset> _slideAnimation;
  late Animation<double> _fadeAnimation;
  bool _isVisible = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    _slideAnimation = Tween<Offset>(
      begin: const Offset(1, 0),
      end: Offset.zero,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut));
    _fadeAnimation = Tween<double>(
      begin: 0,
      end: 1,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn));
  }

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

  void _toggleVisibility() {
    setState(() => _isVisible = !_isVisible);
    _isVisible ? _controller.forward() : _controller.reverse();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: _toggleVisibility,
            child: Text(_isVisible ? '隐藏' : '显示'),
          ),
          const SizedBox(height: 20),
          SlideTransition(
            position: _slideAnimation,
            child: FadeTransition(
              opacity: _fadeAnimation,
              child: Container(
                width: 200,
                height: 100,
                color: Colors.blue,
                alignment: Alignment.center,
                child: const Text('目标内容', style: TextStyle(color: Colors.white)),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

两种方案都能实现你需要的动效:方案1更简洁,适合快速开发;方案2灵活性更高,支持自定义动画细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 16:03:26