Flutter - 从父类或其他子类中调用子类的动画功能。

问题描述 投票:3回答:1

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

我只是需要能够触发styleMenu的动画函数,通过按下dropDownMenu里面的按钮来弹出这个菜单,但我就是不知道该怎么做! 我相信一定有一个简单的方法,但我无法在网上找到任何东西。

有什么高手吗?

animation callback flutter
1个回答
0
投票

我刚刚在研究一个类似的问题。使用Streams、带ChangeNotifiers的Provider或继承的widgets都是可行的选择。如果你确实想简单地在父类调用setState时触发子类widget动画,你可以通过在子类widget中使用didUpdateWidget来实现,如下图所示。

  @override
  void didUpdateWidget(ImageHeartAnimation oldWidget) {
    _controller.forward().orCancel;
    super.didUpdateWidget(oldWidget);
  }
© www.soinside.com 2019 - 2024. All rights reserved.