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

如何使用Animations包的SharedAxisTransition实现Flutter动画Stepper效果

问题根源

你当前的写法将完整Stepper组件作为PageTransitionSwitcher的子元素,当stepperIndex变更时会触发整个Stepper参与过渡重建,因此左侧的步骤指示器、垂直分割线都会跟着动画,不符合需求。

解决方案

核心逻辑是仅对Step的content内容区域做过渡,保留Stepper框架部分(指示器、分割线)的原有状态不参与动画,具体实现如下:

  1. 新增变量记录步进方向,用于控制过渡动画的播放方向,符合前进/后退的交互直觉
  2. 改造Step列表的生成逻辑,仅当前激活的Step返回带过渡动画的内容,其余Step返回空占位组件
  3. 移除外层包裹Stepper的PageTransitionSwitcher,避免整个组件参与过渡

完整实现代码

import 'package:animations/animations.dart';

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

  @override
  State<AnimatedStepperPage> createState() => _AnimatedStepperPageState();
}

class _AnimatedStepperPageState extends State<AnimatedStepperPage> {
  int _currentStep = 0;
  // 记录步进方向:前进为true,后退为false
  bool _isForward = true;

  // 生成每个步骤的自定义内容
  Widget _buildStepContent(int stepIndex) {
    return Container(
      alignment: Alignment.centerLeft,
      padding: const EdgeInsets.symmetric(vertical: 16),
      child: Text('这是步骤 ${stepIndex + 1} 的内容'),
    );
  }

  List<Step> get _steps => List.generate(3, (index) => Step(
    title: Text('步骤 ${index + 1}'),
    // 仅当前激活的步骤返回带过渡的内容,其余返回空占位
    content: index == _currentStep ? PageTransitionSwitcher(
      duration: const Duration(milliseconds: 300),
      reverse: !_isForward,
      transitionBuilder: (child, animation, secondaryAnimation) => SharedAxisTransition(
        transitionType: SharedAxisTransitionType.vertical,
        animation: animation,
        secondaryAnimation: secondaryAnimation,
        child: child,
      ),
      child: _buildStepContent(index, key: ValueKey(index)),
    ) : const SizedBox.shrink(),
    isActive: index <= _currentStep,
  ));

  void _handleStepContinue() {
    if (_currentStep < _steps.length - 1) {
      setState(() {
        _isForward = true;
        _currentStep += 1;
      });
    }
  }

  void _handleStepCancel() {
    if (_currentStep > 0) {
      setState(() {
        _isForward = false;
        _currentStep -= 1;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: const FliAppBar(),
      body: Stepper(
        currentStep: _currentStep,
        steps: _steps,
        onStepContinue: _handleStepContinue,
        onStepCancel: _handleStepCancel,
      ),
    );
  }
}

效果优化说明

如果需要调整内容区域的边距、分割线样式,可以通过Theme组件包裹Stepper,修改stepperTheme的相关配置即可,不会影响过渡动画的生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:00:01