flutterflutter-cupertinoflutter-alertdialogcupertinopicker

Flutter cupertinoPicker value not changing


I'm trying to use CupertinoPicker on a AlertDialog widget but the values are do not change. The same code work when it's not the AlertDialog widget. What's happening?

Button to press to show AlertDialog:

ElevatedButton(
 onPressed: () {

showDialog(
context: context, builder: (context) => AlertDialog(
content:Builder(builder: (context) {
return SizedBox(
child: Column(
children: [
....

]
)
)
}
)
)
}
)

One of the children is the CupertinoWidget and this is the code:

In the class widget int selectedValue = 0;

CupertinoButton.filled(child: Text('$selectedValue'),
onPressed: () =>showCupertinoModalPopup(context:context,builder: (_) =>
SizedBox(width:screenWidth *0.3,height:screenHeight *0.25,
child:CupertinoPicker(backgroundColor:Colors.white,
itemExtent:30,
scrollController:FixedExtentScrollController(initialItem: 1),
children: const [Text('0'),
                 Text('1'),
                 Text('2'),
                 Text('3'),
                 Text('4'),
                 Text('5'),
                 Text('6'),
                 Text('7'),
                 ],
onSelectedItemChanged:(intvalue) {
    setState(() {selectedValue =value;
                                                                          });
                                                                        },
                                                                      ),
                                                                    ),
                                                                  ),
                                                                ),

With this the value in Text('$selectedValue') do not change. But when I write the same code on a new Scaffold screen it works perfectly. Any reason?


Solution

  • create a separate StatefullWidget for AlertDialog:

    ElevatedButton(
     onPressed: () {
    
    showDialog(
    context: context, builder: (context) => Dialog()
    )
    }
    )
    
    
    
    
    class Dialog extends StatefulWidget {
      const Dialog({super.key});
    
      @override
      State<Dialog> createState() => _DialogState();
    }
    
    class _DialogState extends State<Dialog> {
      @override
      Widget build(BuildContext context) {
        return AlertDialog(content: Builder(builder: (context) {
          return SizedBox(child: Column(children: []));
        }));
      }
    }
    
    
    

    You can also use statefulBuilder instead of builder so you will be able to change state inside AlertDialog:

     showDialog(
                context: context,
                builder: (context) => AlertDialog(content: StatefulBuilder(
                      builder: ((context, setState) {
                        return Column();
                      }),
                    )))
    
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primaryColor: Colors.indigo,
            useMaterial3: true,
          ),
          home: const MyHomePage(),
        );
      }
    }
    
    int currentValue = 0;
    DateTime date = DateTime(DateTime.april);
    
    //use stateful widget when you want to change state
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              //button to show dialog
              ElevatedButton(
                child: Text("show Dialog "),
                onPressed: () {
                  showDialog(context: context, builder: (context) => Dialog());
                },
              ),
            ],
          ),
        );
      }
    }
    
    class Dialog extends StatefulWidget {
      Dialog({super.key});
    
      @override
      State<Dialog> createState() => _DialogState();
    }
    
    class _DialogState extends State<Dialog> {
      @override
      Widget build(BuildContext cont) {
        return SizedBox(
          height: 200,
          child: AlertDialog(
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text("$currentValue"),
                ),
                Text('$date'),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: SizedBox(
                    height: 30,
                    child: CupertinoPicker(
                      scrollController:
                          FixedExtentScrollController(initialItem: currentValue),
                      itemExtent: 30,
                      children: [
                        Text('0'),
                        Text('1'),
                        Text('2'),
                        Text('3'),
                        Text('4'),
                        Text('5'),
                        Text('6'),
                        Text('7'),
                        Text('8'),
                        Text('9'),
                      ],
                      onSelectedItemChanged: (newValue) {
                        setState(() {
                          currentValue = newValue;
                        });
                      },
                    ),
                  ),
                ),
                SizedBox(
                  height: 200,
                  child: CupertinoDatePicker(onDateTimeChanged: (newDate) {
                    setState(() {
                      print(date);
                      print(newDate);
                      date = newDate;
                    });
                  }),
                ),
              ],
            ),
          ),
        );
      }
    }