传递正确的上下文以在flutter中构建按钮小部件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传递正确的上下文以在flutter中构建按钮小部件相关的知识,希望对你有一定的参考价值。

我有以下代码:

class RadialMenu extends StatefulWidget {
  @override
  _RadialMenuState createState() => _RadialMenuState();
}

class _RadialMenuState extends State<RadialMenu>
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      duration: Duration(milliseconds: 900),
      vsync: this,
    );
  }

  @override
  Widget build(BuildContext context) {
    return RadialAnimation(controller: controller);
  }
}

class RadialAnimation extends StatelessWidget {
  RadialAnimation({Key key, this.controller})
      :
        super(key: key);

  final AnimationController controller;
  final Animation<double> scale;
  final Animation<double> translation;
  final Animation<double> rotation;

  build(context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (currentContext, builder) {
        return Transform.rotate(
          angle: radians(rotation.value),
          child: Stack(
            alignment: Alignment.center,
            children: <Widget>[
              _buildButton(currentContext, 0, 'Train Arrivals',
                  color: Colors.red, icon: FontAwesomeIcons.personBooth),

              Transform.scale(
                scale: scale.value - 1.5,
                child: FloatingActionButton(
                  child: Icon(FontAwesomeIcons.timesCircle),
                  onPressed: _close,
                  backgroundColor: Colors.red,
                ),
              ),
              Transform.scale(
                scale: scale.value,
                child: FloatingActionButton(
                  child: Icon(FontAwesomeIcons.train),
                  onPressed: _open,
                  backgroundColor: Colors.black,
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  _open() {
    controller.forward();
  }

  _close() {
    controller.reverse();
  }

  _buildButton(
    final BuildContext context,
    double angle,
    String text, {
    Color color,
    IconData icon,
  }) {
    final double rad = radians(angle);
    return Transform(
      transform: Matrix4.identity()
        ..translate(
          (translation.value) * cos(rad),
          (translation.value) * sin(rad),
        ),
      child: FloatingActionButton(
        child: Icon(icon),
        backgroundColor: color,
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (anotherContext) {
              return SecondRoute();
            }),
          );
        },
        tooltip: text,
      ),
    );
  }
}

class SecondRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Title'),
      ),
      body: Center(
        child: Text('Data'),
      ),
    );
  }
}

_buildButton部分我想包括一个Navigator.push实例,以便点击该按钮我需要去另一条路线。

但是目前这是不可能的,因为根据我的理解,Navigator.push期望我不会在这里传递构建上下文。

请帮助我在这里传递正确的上下文,或者我还能做些什么来解决这个问题?

答案

由于您在builder: (context, builder)方法中创建了按钮,因此此方法为您提供的上下文与您可以通过参数传递给_buildButton(BuildContext context, ...)函数并在Navigator.push方法内部使用相同的上下文并转到另一个路径的上下文相同。

更新我之前告诉的所有答案都是正确的,但在你的情况下会出现黑屏,因为你在屏幕上有很多FAB,你需要为每个FAB中的tagHero属性提供一个独特的值。在FloatActionButton porperty之前,代码中的更改是在onPress的构造函数中。我只会在这里放置源的主要部分。

build(context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (currentContext, builder) {
        return Transform.rotate(
          angle: radians(rotation.value),
          child: Stack(
            alignment: Alignment.center,
            children: <Widget>[
              _buildButton(currentContext, 0, 'Train Arrivals',
                  color: Colors.red, icon: FontAwesomeIcons.personBooth),
              _buildButton(currentContext, 45, 'Train Fare Enquiry',
                  color: Colors.green, icon: FontAwesomeIcons.moneyBill),
              _buildButton(currentContext, 90, 'Live Train Status',
                  color: Colors.cyan[400], icon: FontAwesomeIcons.hourglass),
              _buildButton(currentContext, 135, 'Train Between Statios',
                  color: Colors.blue, icon: FontAwesomeIcons.landmark),
              _buildButton(currentContext, 180, 'Train Route',
                  color: Colors.yellow[900], icon: FontAwesomeIcons.route),
              _buildButton(currentContext, 225, 'Train Name/Number',
                  color: Colors.purple, icon: FontAwesomeIcons.train),
              _buildButton(currentContext, 270, 'PNR Status',
                  color: Colors.teal, icon: FontAwesomeIcons.infoCircle),
              _buildButton(currentContext, 315, 'Seat Availability',
                  color: Colors.pinkAccent, icon: FontAwesomeIcons.chair),
              Transform.scale(
                scale: scale.value - 1.5,
                child: FloatingActionButton(
                  child: Icon(FontAwesomeIcons.timesCircle),
                  heroTag: "close", /// Unique tag for this FAB
                  onPressed: _close,
                  backgroundColor: Colors.red,
                ),
              ),
              Transform.scale(
                scale: scale.value,
                child: FloatingActionButton(
                  child: Icon(FontAwesomeIcons.train),
                  heroTag: "open", /// Unique tag for this FAB
                  onPressed: _open,
                  backgroundColor: Colors.black,
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  _buildButton(
      final BuildContext context,
      double angle,
      String text, {
        Color color,
        IconData icon,
      }) {
    final double rad = radians(angle);
    return Transform(
      transform: Matrix4.identity()
        ..translate(
          (translation.value) * cos(rad),
          (translation.value) * sin(rad),
        ),
      child: FloatingActionButton(
        child: Icon(icon),
        backgroundColor: color,
        heroTag: text, /// HERE I'am using the text as unique tag fot this FAB.
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (anotherContext) {
              return SecondRoute();
            }),
          );
        },
        tooltip: text,
      ),
    );
  }

以上是关于传递正确的上下文以在flutter中构建按钮小部件的主要内容,如果未能解决你的问题,请参考以下文章

遍历列表以在 Flutter 中呈现多个小部件?

Flutter:如何在构造函数中传递值,以便我可以重用我的小部件?

如何在 Flutter 中正确重用 Provider

Flutter Navigator.pop 再次运行小部件构建方法

Flutter:如何在两个小部件之间传递相同的数据?

如何在按钮单击 FLUTTER 上刷新列表小部件数据