HexaCrop
HexaCrop

Reputation: 4263

pass the right context to build button widget in flutter

I have the following code:

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

in the _buildButton section i want to include a Navigator.push instance so that on clicking that button i need to go to another route.

But currently this is not possible, since Navigator.push expects a buildcontext which i am not passing in here, according to my understanding.

Please help me to pass the right context here, or is there anything else that i can do to fix this problem?

Upvotes: 0

Views: 4064

Answers (2)

madison kwynn
madison kwynn

Reputation: 41

Did you try passing onPressed for the _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');})

Upvotes: 0

Marcos Boaventura
Marcos Boaventura

Reputation: 4741

Since you're creating your buttons inside of builder: (context, builder) method, the context which this method provide to you is the same context that you can pass through parameter to _buildButton(BuildContext context, ...) function and use this same context in Navigator.push method inside and go to another route.

Updating the answer all that I told before was true but in your case the black screen appears because since you've many FAB on screen you need provide a unique value to tagHero property in each FAB that you have. The changes in your code are in constructor of FloatActionButton before onPress porperty. I will putting only the main parts of the source here.

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

Upvotes: 1

Related Questions