Flutter, как автоматически анимировать без запуска кнопки

#flutter #flutter-layout #flutter-animation

#flutter #flutter-макет #flutter-анимация

Вопрос:

У меня есть некоторый код анимации, который бесконечно меняет цвет фона

но проблема в том, что я хочу сделать это без запуска кнопки

и я хочу, чтобы это было автоматизировано в первый раз (при первой загрузке)

ниже приведен код

Я так застрял, кто-нибудь может помочь, пожалуйста

цель состоит в том, чтобы анимировать без триггера, он автоматически запускает анимацию, которая изменяет фон

 import 'package:flutter/material.dart';

class ScreenTime extends StatefulWidget {
 @override
_ScreenTimeState createState() => _ScreenTimeState();
}

class _ScreenTimeState extends State<ScreenTime> {
  List<Color> colorList = [
  Colors.red,
  Colors.blue,
  Colors.green,
  Colors.yellow
 ];
List<Alignment> alignmentList = [
  Alignment.bottomLeft,
  Alignment.bottomRight,
  Alignment.topRight,
  Alignment.topLeft,
];
 int index = 0;
 Color bottomColor = Colors.black54;
 Color topColor = Colors.white10;
 Alignment begin = Alignment.bottomLeft;
 Alignment end = Alignment.topRight;


@override
Widget build(BuildContext context) {

return Scaffold(
    body: Stack(
      children: [
        AnimatedContainer(
          duration: Duration(seconds: 2),
          onEnd: () {
            setState(() {
              index = index   1;
              // animate the color
              bottomColor = colorList[index % colorList.length];
              topColor = colorList[(index   1) % colorList.length];

              //// animate the alignment
              // begin = alignmentList[index % alignmentList.length];
              // end = alignmentList[(index   2) % alignmentList.length];
            });
          },
          decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: begin, end: end, colors: [bottomColor, topColor])),
        ),
        Positioned.fill(
          child: IconButton(
            icon: Icon(Icons.play_arrow),
            onPressed: () {
              setState(() {
                bottomColor = Colors.blue;
              });
            },
          ),
        )
      ],
    ));
 }
}
  

Ответ №1:

Чтобы сохранить как можно больше вашей первоначальной реализации при устранении проблемы, выполните

 WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {bottomColor = Colors.blue;}));
  

в initState не возникло бы проблемы. Это пока выполняется в initState . Вызов этого build приведет к нежелательному дополнительному бесконечному циклу.

Однако использование AnimationController on repeat почти наверняка было бы более чистым внедрением.

Ответ №2:

цель этого вопроса была в основном «как анимировать AnimatedContainer без триггера»

и я думаю, что нашел решение

то, что я сделал, это

просто создайте новую функцию, а затем в методе сборки вызовите метод

и код метода, как показано ниже

  setState(() {
  index = index   1;
  bottomColor = Colors.blue;
});
  

мое второе решение таково, и я думаю, что оно работает

но я беспокоюсь, есть ли у этого какие-либо побочные эффекты

 WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
  

Комментарии:

1. это не было решением, оно работает только при нажатии ctrl s

2. Это действительно должно быть сделано в качестве правки к вашему сообщению с вопросом. Это ваша попытка решить вашу проблему, и это хорошо, но поскольку на самом деле это не отвечает на ваш вопрос, его не следует публиковать как таковой.

Ответ №3:

Используйте это

 bool selected = false;

@override
void initState() {
Future.delayed(const Duration(seconds: 1), () {
  setState(() {
    selected = true;
  });
});
super.initState();
}

@override
Widget build(BuildContext context) {
return Container(
    width: MediaQuery.of(context).size.width,
    height: MediaQuery.of(context).size.height,
    color: Colors.white
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        AnimatedAlign(
          alignment: selected ? Alignment.topRight : Alignment.bottomLeft,
          duration: const Duration(seconds: 1),
          curve: Curves.fastOutSlowIn,
          child: const FlutterLogo(size: 50.0),
        ),
      ],
    ));}
  

Это автоматически запустит анимацию. Вы также можете изменить продолжительность или тип анимации.