typicalCSStudent
typicalCSStudent

Reputation: 29

Flutter | Have a modalbottomsheet and wish to extract it as a widget

I am implementing a sort by function which displays sort options through a modal bottom sheet, I am able to do it in my "Home Page" widget. Would like to check if I can extract these codes and sub it as a widget for better organization. I am unable to do as I am concerned with the return values from the radio value.

Appreciate any help given, thanks!!

Here is my code:

child: TextButton.icon( // Button to press sort 
    onPressed: (() {
      showModalBottomSheet( // show modal 
          shape: RoundedRectangleBorder(
              borderRadius:
                  BorderRadius.circular(10.0)),
          context: context,
          builder: (BuildContext build) {
            return Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[ // radio values 
                RadioListTile(
                  value: 1,
                  groupValue: selectedRadioTile,
                  title: Text(
                      "Case Earliest to Latest"),
                  onChanged: (val) {
                    print(
                        "Radio Tile pressed $val");
                    setSelectedRadioTile(val!);
                    print(selectedRadioTile);
                    Navigator.pop(context);
                  },
                  activeColor:
                      constants.secondaryBlueColour,
                ),
                RadioListTile(
                  value: 2,
                  groupValue: selectedRadioTile,
                  title: Text(
                      "Case Latest to Earliest "),
                  onChanged: (val) {
                    print(
                        "Radio Tile pressed $val");
                    setSelectedRadioTile(val!);
                    print(selectedRadioTile);
                    Navigator.pop(context);
                  },
                  activeColor:
                      constants.secondaryBlueColour,
                )
              ],
            );
          });
    }),
    icon: Icon(
      Icons.sort,
      size: 28,
      color: constants.textGrayColour,
    ),
    label: Text("Sort",
        style: TextStyle(
            color: constants.textGrayColour,
            fontWeight: FontWeight.bold)))),***
    Container(
      margin: const EdgeInsets.only(top: 5),
      width: MediaQuery.of(context).size.width * 0.5,
      decoration: BoxDecoration(
          border: Border(
        left: BorderSide(
            width: 2.0,
            color:
                constants.categoryButtonBackgroundColour),
        bottom: BorderSide(
            width: 2.0,
            color:
                constants.categoryButtonBackgroundColour),
      )),
      child: TextButton.icon(
          onPressed: () {},
          icon: Icon(Icons.filter_alt,
              size: 28, color: constants.textGrayColour),
          label: Text("Filter",
              style: TextStyle(
                  color: constants.textGrayColour,
                  fontWeight: FontWeight.bold))),
    ),
  ],
),

I implemented a SortWidget() but am wondering how I can return the current radio value to my homepage and set the state in the homepage based on the radio value

Upvotes: 1

Views: 1608

Answers (2)

Aakash Kumar
Aakash Kumar

Reputation: 1187

showModalBottomSheet is actually a function which can't converted to widget without having some other widget in place. What you can do is, create a function which hold code of this showModalBottomSheet and call that function on button click.

But if you want to create a separate widget then you can create the widget from the internal code of the showModalBottomSheet which starts with return Column.

You need to create a widget which can take two properties which are int variable named selected and a Function named setSelected. Then you can call that widget from inside the showModalBottomSheet and pass two props from your page. This selected will be set as selectedRadioTile & setSelected will be set as setSelectedRadioTile.

Example Code

class BottomFilter extends StatelessWidget {
  const BottomFilter(
      {Key? key,
      required this.selected,
      required this.setSelected})
      : super(key: key);

  final int selected;
  final Function setSelected;
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        // radio values
        RadioListTile(
          value: 1,
          groupValue: selected,
          title: Text("Case Earliest to Latest"),
          onChanged: (val) {
            print("Radio Tile pressed $val");
            setSelected(val!);
            print(selected);
            Navigator.pop(context);
          },
          activeColor: Colors.amber,
        ),
        RadioListTile(
          value: 2,
          groupValue: selected,
          title: Text("Case Latest to Earliest "),
          onChanged: (val) {
            print("Radio Tile pressed $val");
            setSelected(val!);
            print(selected);
            Navigator.pop(context);
          },
          activeColor: Colors.amber,
        )
      ],
    );
  }
}

Call it like this

builder: (BuildContext build) {
          return BottomFilter(selected: selectedRadioTile, setSelected:  setSelectedRadioTile);
        })

Dartpad link to test this code https://dartpad.dev/?id=9359bc416ae48b996085d6f98a977e27

Upvotes: 1

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63604

showModalBottomSheet is a future method, you can use async method for this. and Navigator.pop(context, value); will give you the result. you can also used callback method, seems not needed for your case.

onPressed:()async {
  final value = await showModalBottomSheet(
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
    context: context,
    builder: (BuildContext build) {
      return MyBottomSheetWidget(selectedRadioTile: selectedRadioTile);
    },
  );
   print("$value");
}
class MyBottomSheetWidget extends StatelessWidget {
  // make it statefulWidget if you want to update dialog ui
  const MyBottomSheetWidget({
    Key? key,
    required this.selectedRadioTile,
  }) : super(key: key);

  final selectedRadioTile;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        // radio values
        RadioListTile(
          value: 1,
          groupValue: selectedRadioTile,
          title: Text("Case Earliest to Latest"),
          onChanged: (val) {
            print("Radio Tile pressed $val");

            Navigator.pop(context, val);
          },
        ),
        RadioListTile(
          value: 2,
          groupValue: selectedRadioTile,
          title: Text("Case Latest to Earliest "),
          onChanged: (val) {
            print("Radio Tile pressed $val");
            // setSelectedRadioTile(val!);
            print(selectedRadioTile);
            Navigator.pop(context, val);
          },
        )
      ],
    );
  }
}

Upvotes: 1

Related Questions