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

如何实现带滑入淡出动画的Flutter Spinbox选择组件

要实现你需要的文本滑入滑出+淡入淡出切换效果,我们可以用Flutter自带的AnimatedSwitcher组件,配合SlideTransition+FadeTransition组合实现,具体修改方案如下:


核心改动说明

  1. 新增方向控制变量:在State类中新增变量记录当前是切到下一项还是上一项,用来决定滑动的方向
  2. 替换原有Text组件:用AnimatedSwitcher包裹文本区域,自定义过渡动画实现淡入+滑动效果
  3. 绑定唯一Key:给文本组件绑定和当前索引关联的Key,让AnimatedSwitcher可以识别内容变更触发动画

修改后完整代码

只需要替换原有的_SpinBoxState类代码即可:

class _SpinBoxState<T> extends State<SpinBox<T>> {
  int _currentIndex = 0;
  // 新增变量记录切换方向,true为切下一项,false为切上一项
  bool _isNextDirection = true;

  @override
  void initState() {
    _currentIndex = widget.defaultIndex;
    super.initState();
  }

  void _next() {
    if (_currentIndex < widget.length - 1) {
      _isNextDirection = true;
      setState(() {
        _currentIndex++;
        widget.onChange?.call(widget.values[_currentIndex]);
      });
    }
  }

  void _prev() {
    if (_currentIndex > 0) {
      _isNextDirection = false;
      setState(() {
        _currentIndex--;
        widget.onChange?.call(widget.values[_currentIndex]);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        IconButton(
            onPressed: _prev,
            icon: FaIcon(FontAwesomeIcons.caretLeft)),
        Expanded(
          // 用AnimatedSwitcher包裹文本区域
          child: AnimatedSwitcher(
            duration: const Duration(milliseconds: 200),
            // 自定义过渡动画:淡入淡出+滑动
            transitionBuilder: (Widget child, Animation<double> animation) {
              // 滑动偏移量:切下一项时新内容从右侧进入,旧内容向左离开;切上一项时相反
              final offsetAnimation = Tween<Offset>(
                begin: _isNextDirection ? const Offset(1.0, 0.0) : const Offset(-1.0, 0.0),
                end: Offset.zero,
              ).animate(animation);
              // 组合淡入+滑动效果
              return FadeTransition(
                opacity: animation,
                child: SlideTransition(
                  position: offsetAnimation,
                  child: child,
                ),
              );
            },
            // 必须给子组件加唯一key,才能触发动画
            child: Text(
              widget.labels[_currentIndex],
              key: ValueKey<int>(_currentIndex),
              textAlign: TextAlign.center,
            ),
          ),
        ),
        IconButton(
            onPressed: _next,
            icon: FaIcon(FontAwesomeIcons.caretRight)),
      ],
    );
  }
}

如果需要调整动画速度,修改AnimatedSwitcher的duration参数即可,也可以通过CurvedAnimation自定义动画的速率曲线。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:45:03