如何用AnimatedSwitcher和SlideTransition实现Widget左右滑切效果
Flutter 组件左入右出切换动画实现方案
直接用Flutter内置的AnimatedSwitcher就能实现这个效果,不需要引入第三方依赖,大部分人实现失败都是因为没给子组件加唯一标识、没单独区分进入/退出组件的动画方向。
核心实现要点
- 给
AnimatedSwitcher传入的每一个待切换子组件,必须设置全局唯一的Key,否则框架无法识别组件差异,不会触发切换动画,通常用ValueKey绑定组件对应的业务数据即可。 - 重写
transitionBuilder属性,分别判断当前渲染的是进入的新组件还是退出的旧组件,给二者设置反向的水平位移动画:新组件初始位置在屏幕左侧外,动画过程中移动到正常位置;旧组件初始位置在正常位置,动画过程中移动到屏幕右侧外。 - 可以搭配透明度动画弱化滑动的生硬感,不需要的话直接去掉
FadeTransition即可。
可直接复用的代码示例
import 'package:flutter/material.dart'; class SlideSwitchContainer extends StatefulWidget { const SlideSwitchContainer({super.key}); @override State<SlideSwitchContainer> createState() => _SlideSwitchContainerState(); } class _SlideSwitchContainerState extends State<SlideSwitchContainer> { // 切换标识,实际开发替换成你的业务状态即可 int _activeIndex = 0; // 待切换的组件列表 final List<Widget> _switchWidgets = const [ Center(child: Text('组件A', style: TextStyle(fontSize: 28))), Center(child: Text('组件B', style: TextStyle(fontSize: 28))), ]; @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: double.infinity, height: 320, child: AnimatedSwitcher( // 动画时长可根据需求调整 duration: const Duration(milliseconds: 280), // 切换动画构造逻辑 transitionBuilder: (child, baseAnimation) { // 区分进入/退出组件 final isNewWidget = child.key == ValueKey(_activeIndex); // 新组件从左滑入,旧组件向右滑出 final slideTween = isNewWidget ? Tween<Offset>(begin: const Offset(-1, 0), end: Offset.zero) : Tween<Offset>(begin: Offset.zero, end: const Offset(1, 0)); return SlideTransition( position: slideTween.animate(CurvedAnimation( parent: baseAnimation, curve: Curves.easeOutCubic, )), // 不需要淡入淡出效果可以删掉下面的FadeTransition child: FadeTransition( opacity: baseAnimation, child: child, ), ); }, // 给子组件绑定唯一Key child: KeyedSubtree( key: ValueKey(_activeIndex), child: _switchWidgets[_activeIndex], ), ), ), const SizedBox(height: 48), ElevatedButton( onPressed: () { setState(() { _activeIndex = _activeIndex == 0 ? 1 : 0; }); }, child: const Text('触发切换'), ) ], ), ), ); } }
扩展说明
- 如果需要支持反向切换(比如返回场景下新组件从右侧滑入、旧组件向左滑出),只要加一个方向参数控制
Tween的偏移量正负即可,不需要重写核心逻辑。 - 不要手动用
Stack叠加两个组件分别控制动画,性能远低于内置的AnimatedSwitcher,而且退出组件的销毁时机很难控制,容易出现内存占用过高的问题。 - 动画曲线、时长都可以根据设计稿调整,示例里的参数是最接近原生系统组件切换手感的配置。
内容的提问来源于stack exchange,提问作者Matheus Melo
相关产品推荐
相关产品推荐

