Вращающийся контейнер на неопределенный срок

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

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

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)

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


person Ganbayar Gansukh    schedule 20.01.2020    source источник


Ответы (1)


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

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,
      ),
    );
  }

  @override
  void dispose() {
    animationController?.dispose();

    super.dispose();
  }
}

В основном вам нужно создать 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,
  ),
)
person SupposedlySam    schedule 20.01.2020
comment
Спасибо, это дает мне намного больше информации. Я новичок в Dart and Flutter и нахожусь в этом. В настоящее время пытаюсь реализовать в этом классе. https://github.com/flutter/flutter_clock/blob/master/digital_clock/lib/digital_clock.dart Заставить некоторые элементы дизайна постоянно вращаться. - person Ganbayar Gansukh; 21.01.2020
comment
Без проблем! Дайте мне знать, если вам понадобится более подробная информация по чему-либо. - person SupposedlySam; 21.01.2020
comment
Я реализовал этот класс в своем _DigitalClockState классе по ссылке в моем предыдущем комментарии, и я получаю StatefulWidget.createState must return a subtype of State<InfiniteAnimation> - person Ganbayar Gansukh; 21.01.2020
comment
Измените State<InfiniteAnimation> на State<DigitalClock> - person SupposedlySam; 21.01.2020
comment
Может ли мой основной класс _DigitalClockState использовать второй класс, который я создал InfiniteAnimation вместе с классом DigitalClock? как в https://github.com/flutter/flutter_clock/blob/master/digital_clock/lib/digital_clock.dart#L32? - person Ganbayar Gansukh; 21.01.2020
comment
В этом файле так много кода, что я не понимаю, о чем вы говорите. Можете ли вы привести пример того, что вы имеете в виду, когда говорите, например, в ‹link›? - person SupposedlySam; 21.01.2020
comment
Извините. Вот репозиторий обновлений, который включает ваше предложение. https://github.com/nomadme/digital_clock/blob/master/lib/digital_clock.dart - person Ganbayar Gansukh; 21.01.2020
comment
в строке 58 у меня уже есть класс DigitalClock, который создает состояние. Мой вопрос заключался в том, как я могу использовать класс InfiniteAnimation вместе с классом DigitalClock в основном классе. Я использую класс _DigitalClockState, который создает виджет. - person Ganbayar Gansukh; 21.01.2020
comment
Если все, что вы пытаетесь сделать, это заставить что-то вращаться бесконечно, предоставленный мной класс можно просто скопировать / вставить ниже вашего класса часов (или, желательно, в другой файл и импортировать). Затем вы можете просто использовать его в своем классе цифровых часов. Нет необходимости объединять классы вместе. - person SupposedlySam; 21.01.2020