有没有办法在Flare中修改初始动画状态?

时间:2019-10-25 17:45:02

标签: animation flutter flare

我创建了一个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 :(得分:0)

您不需要第二个画板。解决此问题的最简单方法是添加initState方法,并根据与onPressed回调中相同的逻辑设置动画值。请注意,实际上应该在setState调用中完成onPressed中动画值的更改,以确保在动画值更改时更新窗口小部件。

通常更干净的方法是使用像isSubscribed这样的布尔值,而不是将isSubscribed逻辑封装到另一个(Fight)对象中。当isSubscribed更改时,这将允许flutter小部件系统自动在您的State类上调用didUpdateWidget。然后,您可以通过调用setState并更改动画值来响应该更改。您可能会传递一些其他回调,以便在调用onPressed时调用该回调,以便使用此SubUnsubButton的小部件可以更改isSubscribed值。

您可能根本不需要有状态的小部件,请查看Flare-Flutter存储库中的checkbox示例。它会在启动时显示一个带有随机选择值的复选框列表,用于检查是否选中它们。 SmileySwitch复选框类被实现为无状态窗口小部件,而实现的Settings类仅对值进行迭代,为每个值创建一个SmileySwitch,然后通过根据需要更改值来响应onToggle回调。这应该与您尝试执行的操作非常相似。

答案 1 :(得分:0)

正如Luigi在他的链接示例中所展示的,snapToEnd flare actor属性是解决此问题所需的全部。首次将动画渲染到正确状态时,将其设置为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';
                    })

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