传递正确的上下文以快速构建按钮小部件

时间:2019-03-14 19:05:38

标签: flutter widget

我有以下代码:

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期望我不会在此处传递的buildcontext。

请帮助我在此处传递正确的上下文,或者我还有其他方法可以解决此问题?

2 个答案:

答案 0 :(得分:1)

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

更新我之前回答的所有内容都是正确的,但是在您的情况下,出现黑屏是因为屏幕上有很多FAB,因此您需要为每个FAB中的tagHero属性提供唯一值。您的代码中的更改在FloatActionButton之前属于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,
      ),
    );
  }

答案 1 :(得分:0)

您是否尝试将onPressed传递给_buildButton

_buildButton(
  final BuildContext context,
  double angle,
  String text, {
  Color color,
  IconData icon,
  onPressed
}) 



_buildButton(currentContext, 0, 'Train Arrivals',
color: Colors.red, icon: FontAwesomeIcons.personBooth, onPressed() { 
Navigator.of(context).pushNamed( '/route');})