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