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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:45:37