Search code examples
flutterradio-buttonnavigator

Navigator pass value of selected radio or text to next page in flutter


I want to show the radio result in the next page, but I don't know how to pass the data of radio or the words in the text field to the next page.

What I want is that if I choose Living Room, then the next page will show 'Location is Living Room'. If I choose others and also type 'game room' in the last option, then the next page will show 'Location is game room'.

How to do this with Navigator and radio?

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Select A Location',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      routes: <String, WidgetBuilder>{
        '/': (context) => SelectALocation(),
        '/nextpage': (context) => NextPage(),
      },
    );
  }
}

class SelectALocation extends StatefulWidget {
  @override
  _SelectALocationState createState() => _SelectALocationState();
}

class _SelectALocationState extends State<SelectALocation> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SingleChildScrollView(
          child: Column(
        children: <Widget>[
          Text('Select a location'),
          SelectLocationWidget(),
          RaisedButton(
            child: Text('Next'),
            onPressed: () {
              Navigator.pushNamed(context, '/nextpage', arguments: 'Location');
            },
          )
        ],
      )),
    );
  }
}

enum Location {livingRoom, bedroom, kitchen, others }

class SelectLocationWidget extends StatefulWidget {
  SelectLocationWidget({Key key}) : super(key: key);

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

class _SelectLocationWidgetState extends State<SelectLocationWidget> {
  Location _location = Location.livingRoom;
  final TextEditingController _locationOthersController =
      new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        RadioListTile<Location>(
          title: const Text('Living Room'),
          value: Location.livingRoom,
          groupValue: _location,
          onChanged: (Location value) {
            setState(() {
              _location = value;
            });
          },
        ),
        RadioListTile<Location>(
          title: const Text('Bedroom'),
          value: Location.bedroom,
          groupValue: _location,
          onChanged: (Location value) {
            setState(() {
              _location = value;
            });
          },
        ),
        RadioListTile<Location>(
          title: const Text('Kitchen'),
          value: Location.kitchen,
          groupValue: _location,
          onChanged: (Location value) {
            setState(() {
              _location = value;
            });
          },
        ),
        RadioListTile<Location>(
          title: TextField(
            controller: _locationOthersController,
            decoration: InputDecoration(
              hintText: 'Others',
            ),
          ),
          value: Location.others,
          groupValue: _location,
          onChanged: (Location value) {
            setState(() {
              _location = value;
            });
          },
        ),
      ],
    );
  }
}

class NextPage extends StatefulWidget {
  @override
  _NextPageState createState() => _NextPageState();
}

class _NextPageState extends State<NextPage> {
  @override
  Widget build(BuildContext context) {
    return Container(child: Text('Location is $Location'));
  }
}

Solution

  • I made a few changes to your code, like changing the SelectLocationWidget from a class to a widget. The code below should work the way you want it, which includes what you type when you choose others:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Select A Location',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          initialRoute: '/',
          routes: <String, WidgetBuilder>{
            '/': (context) => SelectALocation(),
            '/nextpage': (context) => NextPage(),
          },
        );
      }
    }
    
    enum Location {livingRoom, bedroom, kitchen, others }
    
    class SelectALocation extends StatefulWidget {
      @override
      _SelectALocationState createState() => _SelectALocationState();
    }
    
    class _SelectALocationState extends State<SelectALocation> {
      Location location = Location.livingRoom;
      String actualLocation = 'Living Room';
      final TextEditingController locationOthersController = new TextEditingController();
    
      Widget selectLocationWidget() {
        return Column(
          children: <Widget>[
            RadioListTile<Location>(
              title: const Text('Living Room'),
              value: Location.livingRoom,
              groupValue: location,
              onChanged: (Location value) {
                setState(() {
                  location = value;
                  actualLocation = 'Living Room';
                });
              },
            ),
            RadioListTile<Location>(
              title: const Text('Bedroom'),
              value: Location.bedroom,
              groupValue: location,
              onChanged: (Location value) {
                setState(() {
                  location = value;
                  actualLocation = 'Bedroom';
                });
              },
            ),
            RadioListTile<Location>(
              title: const Text('Kitchen'),
              value: Location.kitchen,
              groupValue: location,
              onChanged: (Location value) {
                setState(() {
                  location = value;
                  actualLocation = 'Kitchen';
                });
              },
            ),
            RadioListTile<Location>(
              title: TextField(
                controller: locationOthersController,
                decoration: InputDecoration(
                  hintText: 'Others',
                ),
              ),
              value: Location.others,
              groupValue: location,
              onChanged: (Location value) {
                setState(() {
                  location = value;
                  actualLocation = locationOthersController.text;
                });
              },
            ),
          ],
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                Text('Select a location'),
                selectLocationWidget(),
                RaisedButton(
                  child: Text('Next'),
                  onPressed: () {
                    Navigator.push(
                      context, 
                      MaterialPageRoute(
                        builder: (context) => NextPage(
                          locationText: actualLocation,
                        ),
                      )
                    );
                  },
                )
              ],
            ),
          ),
        );
      }
    }
    
    class NextPage extends StatefulWidget {
      final String locationText;
      NextPage({@required this.locationText});
    
      @override
      _NextPageState createState() => _NextPageState();
    }
    
    class _NextPageState extends State<NextPage> {
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Text('Location is ${widget.locationText}')
        );
      }
    }