如何为IndexedStack添加底部导航切换时的滑动过渡动画?
给IndexedStack+底部导航栏添加页面滑动切换动画
要实现滑动过渡动画同时保留IndexedStack的状态维持能力,我们可以通过记录上一次的页面索引判断滑动方向,用动画控制器驱动SlideTransition完成效果,具体修改如下:
1. 添加动画相关变量
在你的_LoggedHandleState类中新增以下变量,用于记录上一页索引和控制动画:
int _previousPage = 1; late AnimationController _animationController; late Animation<Offset> _slideAnimation;
2. 初始化与销毁动画控制器
在initState中初始化动画控制器,dispose中销毁资源:
@override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 300), // 可根据需求调整动画时长 vsync: this, ); _slideAnimation = Tween<Offset>( begin: Offset.zero, end: Offset.zero, ).animate(_animationController); } @override void dispose() { _animationController.dispose(); super.dispose(); }
3. 修改底部导航栏的点击逻辑
点击切换页面时,先记录上一页索引,根据当前页与上一页的位置关系设置滑动方向,再启动动画:
bottomNavigationBar: BottomNavigationBar( unselectedItemColor: Colors.white60, backgroundColor: Colors.red, selectedItemColor: Colors.white, currentIndex: _selectedPage, onTap: (int index) { setState(() { _previousPage = _selectedPage; _selectedPage = index; // 区分滑动方向:从右往左滑/从左往右滑 if (index > _previousPage) { _slideAnimation = Tween<Offset>( begin: const Offset(1.0, 0.0), end: Offset.zero, ).animate(_animationController); } else { _slideAnimation = Tween<Offset>( begin: const Offset(-1.0, 0.0), end: Offset.zero, ).animate(_animationController); } _animationController.reset(); _animationController.forward(); }); }, items: const <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Hello', ), BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.account_circle), label: 'Account', ), ], ),
4. 给IndexedStack包裹滑动动画
将原有的IndexedStack用SlideTransition包裹,绑定我们定义的滑动动画:
body: SlideTransition( position: _slideAnimation, child: IndexedStack( index: _selectedPage, children: const [HelloView(), HomeView(), UserView()], ), ),
这样修改后,切换底部导航栏时,页面会根据切换方向从侧边滑入,同时IndexedStack会持续保留所有页面的状态,不会因为页面切换丢失数据。
内容的提问来源于stack exchange,提问作者faccio
相关产品推荐
相关产品推荐

