Вращающийся контейнер на неопределенный срок - PullRequest
0 голосов
/ 21 января 2020

Я хотел бы вращать изображение на неопределенный срок.

Этот контейнер является одним из виджетов в стеке и хотел бы, чтобы он непрерывно вращался без остановки.

final AnimationController animation = AnimationController(
  duration: const Duration(milliseconds: 1800),
  vsync: const NonStopVSync(),
)..repeat();

final Tween tween = Tween(begin: 0.0, end: math.pi);

var square = Container(
  width: 100,
  height: 100,
  transform: Matrix4.identity(),
  color: Colors.amber,
);

...

class Foo extends State<Bar> {
    ...


    animation.addListener((){
       square.transform = Matrix4.rotationZ(tween.evaluate(animation));
    });

    Widget build(BuildContext context) {
        return Stack(
           children: [
              ...
              Center(
                 child: square
              )
           ]
        )
    }
}

и я получить это error: 'transform' can't be used as a setter because it's final. (assignment_to_final at [digital_clock] lib/digital_clock.dart:139)

Как бы я сделал то, что я пытаюсь сделать?

1 Ответ

0 голосов
/ 21 января 2020

Попробуйте что-то вроде этого:

class InfiniteAnimation extends StatefulWidget {
  final Widget child;
  final int durationInSeconds;

  InfiniteAnimation({@required this.child, this.durationInSeconds = 2,});

  @override
  _InfiniteAnimationState createState() => _InfiniteAnimationState();
}

class _InfiniteAnimationState extends State<InfiniteAnimation>
    with SingleTickerProviderStateMixin {
  AnimationController animationController;
  Animation<double> animation;
​
  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      vsync: this,
      duration: Duration(seconds: widget.durationInSeconds),
    );
    animation = Tween<double>(
      begin: 0,
      end: 12.5664, // 2Radians (360 degrees)
    ).animate(animationController);
​
    animationController.forward();
​
    animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController.repeat();
      }
    });
  }
​
  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: animationController,
      builder: (context, child) => Transform.rotate(
        angle: animation.value,
        child: widget.child,
      ),
    );
  }
}

Вам необходимо создать StatefulWidget, который смешивает (with ключевое слово) с SingleTickerProviderStateMixin, обеспечивает AnimationController, запускается анимация, а затем, когда анимация завершится, повторите.

AnimationBuilder - это лучший способ сообщить виджету об обновлении каждого кадра без необходимости прослушивания animationController и явного вызова setState.

Вы можете использовать его так:

InfiniteAnimation(
  durationInSeconds: 2, // this is the default value
  child: Icon(
    Icons.expand_more,
    size: 50.0,
    color: Colors.white,
  ),
)
...