在另一个类中调用函数

时间:2020-01-23 01:03:18

标签: flutter

我有两个类:SideNavBar和ContentPage。 SideNavBar包含一个功能,当按下菜单上的某个项目时,该功能可为对象设置动画。 ContentPage包含一个PageView,当它更改时,我想在SideNavBar中使用参数执行该功能。

不包含该功能的ContentPage:

class ContentPage extends StatefulWidget {



@override
  _ContentPageState createState() => _ContentPageState();
}

class _ContentPageState extends State<ContentPage> {

  PageController controller;

  @override
  void initState() {
    controller = PageController(
      initialPage: 6
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: PageView(
        controller: controller,
        scrollDirection: Axis.vertical,
        children: <Widget>[
          menuSlides(),
          menuSlides(),
          menuSlides(),
          menuSlides(),
          menuSlides(),
          menuSlides(),
        ],
        onPageChanged: (int idx) {
          print('animate function from SideNavBar');
        },
      )
    );
  }
}

包含以下功能的SideNavBar:

class SideNavBar extends StatefulWidget {


  @override
  _SideNavBarState createState() => _SideNavBarState();
}

class _SideNavBarState extends State<SideNavBar> with SingleTickerProviderStateMixin{


  int idx = 5;
  double previousPosition = 825.0;

  double _circleFraction = 0.0;
  Animation<double> circleFraction;
  AnimationController controller;

  Animation curvedAnimation;

  @override
  void initState() {
    controller = AnimationController(
      duration: const Duration(milliseconds: 300), vsync: this
    );
    curvedAnimation = CurvedAnimation(parent: controller, curve: Curves.easeInOut);
    super.initState();
  }

    _playAnimation(double pos) {
    circleFraction = Tween(begin: previousPosition, end: pos).animate(curvedAnimation)
      ..addListener(() {
        setState(() {
          previousPosition = _circleFraction;
          _circleFraction = circleFraction.value;
        });

      });
  }

  @override
  Widget build(BuildContext context) {
    return Material(
        child: Container(
      width: MediaQuery.of(context).size.width / 5,
      color: Theme.of(context).primaryColor,
      child: Stack(
        children: <Widget>[CustomPaint(painter: CirclePainter(anim:  _circleFraction == 0 ? previousPosition : _circleFraction, color: Theme.of(context).accentColor),), menuBar(),],
      ),
    ));
  }

  Widget menuBar() {
    return Container(
      width: MediaQuery.of(context).size.width / 7,
      color: Theme.of(context).accentColor,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: GestureDetector(
                onTap: () {
                  _playAnimation(115.0);
                  controller.forward(from: 0.0);
                },
                child: Icon(Icons.account_box, size: 32.0, color: Colors.black,)),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: GestureDetector(
                onTap: () {
                  _playAnimation(180.0);
                  controller.forward(from: 0.0); 
                },
                child: Icon(Icons.star, size: 32.0, color: Colors.black,)),
          ),
          GestureDetector(
              onTap: () {
                _playAnimation(380.0);
                controller.forward(from: 0.0);
              },
              child: Padding(
                  padding: const EdgeInsets.only(bottom: 32.0, top: 128.0),
                  child: RotatedBox(
                    quarterTurns: 3,
                    child: Text(
                      'Desserts',
                      style: stylingMedium(),
                    ),
                  ))),
          GestureDetector(
              onTap: () {
                _playAnimation(530.0);
                controller.forward(from: 0.0);
              },
              child: Padding(
                  padding: const EdgeInsets.symmetric(vertical: 32.0),
                  child: RotatedBox(
                    quarterTurns: 3,
                    child: Text(
                      'Beverages',
                      style: stylingMedium(),
                    ),
                  ))),
          GestureDetector(
              onTap: () {
                _playAnimation(685.0);
                controller.forward(from: 0.0);
              },
              child: Padding(
                  padding: const EdgeInsets.symmetric(vertical: 32.0),
                  child: RotatedBox(
                    quarterTurns: 3,
                    child: Text(
                      'Vegetarian',
                      style: stylingMedium(),
                    ),
                  ))),
          GestureDetector(
              onTap: () {        
                _playAnimation(825.0);
                controller.forward(from: 0.0);
              },
              child: Padding(
                  padding: const EdgeInsets.symmetric(vertical: 32.0),
                  child: RotatedBox(
                    quarterTurns: 3,
                    child: Text(
                      'Combos',
                      style: stylingMedium(),
                    ),
                  ))),
        ],
      ),
    );
  }



  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

class CirclePainter extends CustomPainter {

  CirclePainter({this.anim, this.color});

  final double anim;
  final Color color;

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..style = PaintingStyle.fill
      ..color = color;

    canvas.drawCircle(Offset(42, anim), 40.0, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }

  @override
  bool shouldRebuildSemantics(CustomPainter oldDelegate) {
    return true;
  }

}

1 个答案:

答案 0 :(得分:0)

您不能在getRange之外拨打_playAnimation。在Flutter I wrote a package that might be able to help中,在小部件之间传递状态是很痛苦的,只需确保阅读说明即可。

这里的主要问题是,您可以只全局定义_SideBarNavState,但是您将无权访问_playAnimation。我写了“查找”库来解决这个头疼的问题,但是人们也推荐ProviderBLOC