Есть ли способ изменить начальное состояние анимации в Flare? - PullRequest
0 голосов
/ 25 октября 2019

Я создал анимацию Flare, которая представляет собой просто кнопку подписки / отмены подписки в приложении Flutter.

Анимация запускается при нажатии кнопки, и все выглядит нормально, например, если пользователь подписан, кнопка читает «подписано» после того, как пользователь нажимает ее. Но если пользователь уже подписан и возвращается к соответствующему экрану, кнопка не находится в состоянии подписки. Он остается в исходном состоянии «подписки»

Я работаю с одним артбордом в моем файле Flare. Он имеет две анимации, подписаться и отписаться, которые делают, как они звучат. Анимации воспроизводятся надлежащим образом при нажатии на кнопку, однако состояния не сохраняются при перезагрузке экрана. Например, если я подписался, и, оставив приложение и вернувшись, я вижу кнопку «подписаться», хотя я уже сделал это.

Я не уверен, нужно ли мне 2 отдельныхартборды для этого или есть ли лучший способ?

class SubUnsubButton extends StatefulWidget {
  final Fight fight;
  const SubUnsubButton({
    Key key,
    @required this.fight,
  }) : super(key: key);

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

class _SubUnsubButtonState extends State<SubUnsubButton>
    with TickerProviderStateMixin {
  FlareControls flareController = FlareControls();
  String animation;

  @override
  initState() {
    super.initState();
    widget.fight.userIsSubscribed ? animation = 'Sub' : animation = 'Unsub';
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Container(
            height: 50,
            child: FlatButton(
              child: FlareActor(
                "assets/animations/FightBell.flr",
                artboard: "SubUnsub",
                controller: flareController,
                fit: BoxFit.contain,
                animation: animation,
                sizeFromArtboard: true,
              ),
              onPressed: () {
                // If not subsribed
                FirebaseUser user = Provider.of<FirebaseUser>(context);
                if (!widget.fight.userIsSubscribed) {
                    animation = 'Sub';
                } else {
                    animation = 'Unsub';

                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

Ответы [ 2 ]

0 голосов
/ 31 октября 2019

Как продемонстрировал Луиджи в своем связанном примере, свойство бликового актера snapToEnd - это все, что было необходимо для решения проблемы. Установите его как true при первом рендеринге анимации в правильное состояние. Затем переключите его на false, когда вы получите пользовательский ввод, который должен запустить анимацию.

class SubUnsubButton extends StatefulWidget {
  final Fight fight;
  const SubUnsubButton({
    Key key,
    @required this.fight,
  }) : super(key: key);

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

class _SubUnsubButtonState extends State<SubUnsubButton>
    with TickerProviderStateMixin {
  FlareControls flareController = FlareControls();
  String animation;
  bool _snapToEnd

  @override
  initState() {
    super.initState();
    _snapToEnd = true
    widget.fight.userIsSubscribed ? animation = 'Sub' : animation = 'Unsub';
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Container(
            height: 50,
            child: FlatButton(
              child: FlareActor(
                "assets/animations/FightBell.flr",
                artboard: "SubUnsub",
                controller: flareController,
                fit: BoxFit.contain,
                animation: animation,
                sizeFromArtboard: true,
              ),
              onPressed: () {
                // If not subsribed
                FirebaseUser user = Provider.of<FirebaseUser>(context);
                if (!widget.fight.userIsSubscribed) {
                    setState(() {
                      _snapToEnd = false;
                      animation = 'Sub';
                    });
                } else {
                    setState(() {
                      _snapToEnd = false;
                      animation = 'Unsub';
                    })

                }
              },
            ),
          ),
        ],
      ),
    );
  }
}
0 голосов
/ 27 октября 2019

Вам не нужен второй артборд. Самый простой способ исправить это - добавить метод initState и установить значение анимации на основе той же логики, что и в обратном вызове onPressed. Обратите внимание, что изменение значения анимации в onPressed действительно должно быть сделано в вызове setState , чтобы гарантировать, что виджет обновляется при изменении значения анимации.

В общем, более чистый способ сделать этоиспользование логического значения, такого как isSubscribeed, вместо инкапсуляции логики isSubscribeed в другой (Fight) объект. Это позволит системе виджетов флаттера автоматически вызывать didUpdateWidget в вашем классе State при изменении isSubscribeed. Затем вы можете отреагировать на это изменение, выполнив вызов setState и изменив значение анимации. Вы, вероятно, передадите какой-нибудь другой обратный вызов, который будет вызываться при вызове onPressed, чтобы виджет, использующий этот SubUnsubButton, мог изменить значение isSubscribeed.

Возможно, вам вообще не нужен виджет с отслеживанием состояния, посмотрите на флажок пример в репозитории Flare-Flutter. Он отображает список флажков со случайно выбранными значениями при загрузке, независимо от того, установлены они или нет. Класс флажка SmileySwitch реализован в виде виджета без состояния, в то время как реализующий класс Settings просто перебирает значения, создает для каждого SmileySwitch, а затем отвечает на обратный вызов onToggle, изменяя значениекак надо. Это должно быть очень похоже на то, что вы пытаетесь сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...