我创建了一个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';
}
},
),
),
],
),
);
}
}
答案 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';
})
}
},
),
),
],
),
);
}
}