我有两个动画菜单。 dropDownMenu 工作正常,我可以设置此子级的 onPress 事件以使用回调在父类中执行功能,例如:
class dropDownMenu extends StatefulWidget {
final Function() onPressed;
final String tooltip;
final IconData icon;
final _callback;
dropDownMenu({Key key, this.onPressed, this.tooltip, this.icon, @required void singlePlayerCallbacks(String callBackType) } ):
_callback = singlePlayerCallbacks, super(key: key);
@override
_dropDownMenuState createState() => _dropDownMenuState();
}
class _dropDownMenuState extends State<dropDownMenu>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget> [
Column(
Container(
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: isOpened == true? (){
widget?._callback('dice');
} : () {},
),
),
),
],
);
}
然后在父类中:
class SinglePlayerMode extends StatefulWidget {
@override
SinglePlayerModeParentState createState() => SinglePlayerModeParentState();
}
class SinglePlayerModeParentState extends State<SinglePlayerMode> {
callBacks(String callBackType) {
switch(callBackType) {
case 'dice':
{
diceVisible = !diceVisible;
int rng = new Random().nextInt(19) + 1;
setState(() {
diceResult = rng;
});
}
}
break;
}
@override
Widget build(BuildContext context) {
child: Scaffold(
body: Container(
Padding(
padding: EdgeInsets.all(0.0),
child: dropDownMenu(
singlePlayerCallbacks: callBacks,
),
),
),
),
}
作为一个简单的例子,这工作得很好。
接下来我需要做的是创建另一个动画菜单,称为 styleMenu,它在按下 dropDownMenu 中的按钮时进行动画处理。这是我遇到巨大障碍的地方。老实说,我不介意如何完成这项工作,我只需要完成它。这是我目前正在尝试的,但没有成功:
在 dropDownMenu 中,我有另一个按钮,首先回调父级:
Container(
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: isOpened == true? (){
widget?._callback('theme');
} : () {},
),
),
),
这会再次触发父级的回调函数,使用不同的 switch case:
callBacks(String callBackType) {
case 'theme':
{
styleMenuState().animate();
}
break;
我显然不能这样做,因为它告诉我我正在尝试为空对象设置动画。就像我必须以某种方式实例化 styleMenu 才能从此处调用此函数,但我不知道如何执行此操作,甚至不知道如何执行此操作。
我的 styleMenu 类(摘录):
class styleMenu extends StatefulWidget {
final Function() onPressed;
final String tooltip;
final IconData icon;
final _callback;
final VoidCallback animate;
styleMenu({this.onPressed, this.tooltip, this.animate, this.icon, @required void singlePlayerCallbacks(String callBackType) } ):
_callback = singlePlayerCallbacks;
@override
styleMenuState createState() => styleMenuState();
}
class styleMenuState extends State<styleMenu>
with SingleTickerProviderStateMixin {
bool isOpened = false;
AnimationController animationController;
Animation<Color> _buttonColor;
Animation<double> _animateIcon;
Animation<double> _translateButton;
Curve _curve = Curves.easeOut;
double _fabHeight = 52.0;
@override
initState() {
animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 600))
..addListener(() {
setState(() {});
});
_animateIcon =
Tween<double>(begin: 0.0, end: 1.0).animate(animationController);
_buttonColor = ColorTween(
begin: Colors.blue,
end: Colors.red,
).animate(CurvedAnimation(
parent: animationController,
curve: Interval(
0.0,
1.0,
curve: Curves.linear,
),
));
_translateButton = Tween<double>(
begin: 0.0,
end: _fabHeight,
).animate(CurvedAnimation(
parent: animationController,
curve: Interval(
0.0,
1.0,
curve: _curve,
),
));
super.initState();
}
@override
dispose() {
animationController.dispose();
super.dispose();
}
animate() {
if (!isOpened) {
styleMenuState().animationController.forward();
} else {
styleMenuState().animationController.reverse();
}
isOpened = !isOpened;
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget> [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0,
_translateButton.value,
0,
),
child: blueTheme(),
),
Transform(
transform: Matrix4.translationValues(
0,
_translateButton.value * 2,
0,
),
child: greenTheme(),
),
Transform(
transform: Matrix4.translationValues(
0,
_translateButton.value * 3,
0,
),
child: redTheme(),
),
blackTheme(),
],
),
],
),
);
}
同样,我只需要能够从 styleMenu 触发动画功能,通过按下 dropDownMenu 内的按钮弹出此菜单,但我无法理解如何执行此操作!我确信一定有一种简单的方法,但我无法在网上找到任何东西。
那里有专家吗?
最佳答案
我刚刚在处理类似的问题。使用 Streams、Provider with ChangeNotifiers 或继承的小部件都是可行的选择。如果您确实想简单地触发从父级调用的 setState 上的子部件动画,您可以通过使用子部件中的 didUpdateWidget 来实现,如下所示
@override
void didUpdateWidget(ImageHeartAnimation oldWidget) {
_controller.forward().orCancel;
super.didUpdateWidget(oldWidget);
}
关于animation - Flutter - 从父类或另一个子类调用子类的动画函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55035697/