'How to get a value from a dialog in flutter?

I am creating an app and I want to show a dialog for the user which contains a slider to pick a value.

the problem comes here, I want to get the value of that slider which user picked and deal with it.

I am using the dialog as a stateful widget and everything works okay except returning the value as I've mentioned.


The Widget

class Dialog extends StatefulWidget {
  @override
  _DialogState createState() => _DialogState();

  final double val;

  Dialog({this.val,});
}

class _DialogState extends State<Dialog> {
  double value = 0;

  @override
  void initState() {
    super.initState();
    value = widget.val;
  }
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Slider(
        value: value,
        min: 0,
        max: 100,
        onChanged: (va) {
          setState(() {
            value = va;
          });
        },
      ),
    );
  }
}

show dialog code

double vale = 0;

-------

() async {
            await showDialog(
              context: context,
              builder: (context) => Dialog(
                val: vale,
              ),
            );
          }


Solution 1:[1]

You can access and use the value that comes from your dialog option like this:

showDialog(
  context: context,
  builder: (context) => Dialog(
    val: vale,
  ),
).then((valueFromDialog){
  // use the value as you wish
  print(valueFromDialog);
});

The .then()will be triggered after the user selects an option on your Dialog.

Solution 2:[2]

What is missing is that you need to return the value when closing the dialog, like this:

return AlertDialog(
  title: Slider(
    value: value,
    min: 0,
    max: 100,
    onChanged: (va) {
      setState(() {
        value = va;
      });
    },
  ),
  actions: [
    ElevatedButton(
        onPressed: () => Navigator.pop(context),
        child: Text('cancel')),
    ElevatedButton(
        onPressed: () => Navigator.pop(context, value),
        child: Text('confirm')),
  ],
);

It will then be returned by the showDialog function as expected as a Future

Solution 3:[3]

I can suggest you 2 different ways. Here's the explanation:

you can use either

1) Navigator.pop(context, value);

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Column(
        children: [
          Slider(
            value: value,
            min: 0,
            max: 100,
            onChanged: (va) {
              setState(() {
                value = va;
              });
            },
          ),
          const SizedBox(height: 15),
          ElevatedButton(
           // Pass the value you want to return here ---------------|
            onPressed: () => Navigator.pop(context, value), //<-----|
            child: const Text('confirm'),
          ),
        ],
      ),
    );
  }

here's how to call it:

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // You can get the returned value here -------------|
            double? val = await showDialog<double>(  //<--------|
              context: context,
              builder: (context) => const DialogOne(),
            );
            print('Dialog one returned value ---> $val');
          },
          child: const Text('Show Dialog One'),
        ),
      ),
    );
  }

2) Callback function.

class DialogTwo extends StatefulWidget {
  @override
  _DialogTwoState createState() => _DialogTwoState();
  
  // The callback function with data you want to return -------|
  final Function(double value) onConfirm;      // <------------|     

  const DialogTwo({
    Key? key,
    required this.onConfirm,
  }) : super(key: key);
}

class _DialogTwoState extends State<DialogTwo> {
  double value = 0;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Column(
        children: [
          Slider(
            value: value,
            min: 0,
            max: 100,
            onChanged: (val) {
              setState(() {
                value = val;
              });
            },
          ),
          const SizedBox(height: 15),
          ElevatedButton(
            onPressed: () {
              // Call the function here to pass back the value -----|
              widget.onConfirm(value);       // <-------------------|
              Navigator.pop(context);
            },
            child: const Text('confirm'),
          ),
        ],
      ),
    );
  }
}

Here's how to call it:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            showDialog<String>(
              context: context,
              builder: (context) => DialogTwo(
                // You can use the callback function like this -------|
                onConfirm: (double value) {       // <----------------|
                  print('Dialog two returned value ---> $value');
                },
              ),
            );
          },
          child: const Text('Show Dialog Two'),
        ),
      ),
    );
  }

That's it, Hope my answer will help you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 João Soares
Solution 2 JulienV
Solution 3 xSuperMu