Flutter-从父级或另一个子类调用子级的动画函数

时间:2019-03-07 03:43:19

标签: animation callback flutter

我有两个动画菜单。 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');
      } : () {},
    ),
  ),
),

使用不同的切换方式再次触发父级的回调函数:

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(),
          ],
        ),
      ],
    ),
  );
 } 

同样,我只需要能够通过从dropMenu内按下一个按钮来触发styleMenu的动画功能,以弹出此菜单,我只是不知道该怎么做!我相信肯定有一种简单的方法,但是我无法在网上找到任何东西。

那里有专业人士吗?

1 个答案:

答案 0 :(得分:0)

我只是在研究类似的问题。使用Streams,带有ChangeNotifiers的Provider或继承的窗口小部件是可行的选项。如果您确实想在父级调用的setState上简单触发子级小部件动画,则可以使用子级小部件中的didUpdateWidget进行操作,如下所示

  @override
  void didUpdateWidget(ImageHeartAnimation oldWidget) {
    _controller.forward().orCancel;
    super.didUpdateWidget(oldWidget);
  }
相关问题