首页 文章

如何在Flutter中定义离散动画?

提问于
浏览
2

是否有可能在颤振中创建一个不会不断改变其 Value 的动画,但只能在给定的时间间隔内?

我现在有以下代码,但我确信有更好的解决方案 .

int aniValue = 0;
  bool lock = false;
  _asyncFunc() async {
    if(lock) return;
    else     lock = true;

    await new Future.delayed(const Duration(milliseconds: 50), () {
      ++aniValue;

      if (aniValue == 41) {
        aniValue = 0;
      }
    });

    lock = false;

    setState(() {});
    _asyncFunc();
  }

1 回答

  • 3

    可以为动画定义曲线;有非线性进展 .

    颤动不提供“阶梯”曲线,但你可以很容易地制作一个:

    class StepCurve extends Curve {
      final int stepCount;
    
      const StepCurve([this.stepCount = 2]) : assert(stepCount > 1);
    
      @override
      double transform(double t) {
        final progress = (t * stepCount).truncate();
        return 1 / (stepCount - 1) * progress;
      }
    }
    

    然后,您可以通过将其与 CurveTween 相关联来自由使用它:

    @override
    Widget build(BuildContext context) {
      return AlignTransition(
        alignment: AlignmentGeometryTween(
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
        )
            .chain(CurveTween(curve: const StepCurve(5)))
            .animate(animationController),
        child: Container(
          color: Colors.red,
          width: 42.0,
          height: 42.0,
        ),
      );
    }
    

    enter image description here


    另一种解决方案是使用TweenSequence .

    enter image description here

    class TestAnim extends StatefulWidget {
      @override
      _TestAnimState createState() => _TestAnimState();
    }
    
    class _TestAnimState extends State<TestAnim>
        with SingleTickerProviderStateMixin {
      AnimationController animationController;
    
      @override
      void initState() {
        super.initState();
        animationController = AnimationController(
          vsync: this,
          duration: const Duration(seconds: 1),
        )..repeat();
      }
    
      @override
      Widget build(BuildContext context) {
        final colors = <Color>[
          Colors.red,
          Colors.blue,
          Colors.lime,
          Colors.purple,
        ];
    
        return DecoratedBoxTransition(
          decoration: TweenSequence(colorsToTween(colors).toList())
              .animate(animationController),
          child: const SizedBox.expand(),
        );
      }
    }
    
    Iterable<TweenSequenceItem<Decoration>> colorsToTween(
        List<Color> colors) sync* {
      for (int i = 0; i < colors.length - 1; i++) {
        yield TweenSequenceItem<Decoration>(
          tween: DecorationTween(
            begin: BoxDecoration(color: colors[i]),
            end: BoxDecoration(color: colors[i + 1]),
          ),
          weight: 1.0,
        );
      }
    }
    

相关问题