I have a Dialog Widget, there are a Button and Text field there. On pressing the button there is a function wich setState()
and variable change. I do not see these changes instantly on a screen in the text field, I need to close and open Dialog again. Why and how can I make it happen (so the whole class/parent will be rebuilt? (It is about "Get location" button and next field)
class MyDialog extends StatefulWidget {
MyDialogState createState() => MyDialogState();
}
class MyDialogState extends State<MyDialog> {
String userLocation;
double sleepLength;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)
),
elevation: 20,
child: ListView(
children: <Widget>[
FlatButton(
child: Text("Get location $userLocation"),
onPressed: () {
final Geolocator geolocator = Geolocator();
geolocator
.getCurrentPosition()
.then((Position position) async {
List<Placemark> place = await geolocator
.placemarkFromCoordinates(position.latitude, position.longitude);
Placemark p = place[0];
setState(() {
//userLocation = "${p.locality}, ${p.country}";
userLocation = Random().nextInt(10).toString();
print("A");
});
}).catchError((e) {
print("------------");
print(e);
print("------------");
});
},
),
Padding(
padding: EdgeInsets.all(10),
child: Center(child: Text("$userLocation"))
),
Divider(),
FlatButton(
child: Text("Set sleep length"),
onPressed: () {
//TODO
},
),
Padding(
padding: EdgeInsets.all(10),
child: Center(child: Text("$sleepLength"))
),
Divider(),
],
)
);
}
);
},
child: Icon(
Icons.settings
),
backgroundColor: Colors.black12,
);
}
}
In my case StatefulBuilder
works. StatefulBuilder
is best used in situations where you have a medium/large widget tree and state needs to be introduced for a small subsection of that tree.
wrap you child with StatefulBuilder
hope it helps..
You have to wrap Dialog with return StatefulBuilder builder: ...
and carefully about }
and );
because in this case it is a long string
code snippet
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Dialog(
...
);
},
);
your code with StatefulBuilder
class MyDialog extends StatefulWidget {
MyDialogState createState() => MyDialogState();
}
class MyDialogState extends State<MyDialog> {
String userLocation;
double sleepLength;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)),
elevation: 20,
child: ListView(
children: <Widget>[
FlatButton(
child: Text("Get location $userLocation"),
onPressed: () {
final Geolocator geolocator = Geolocator();
geolocator
.getCurrentPosition()
.then((Position position) async {
List<Placemark> place =
await geolocator.placemarkFromCoordinates(
position.latitude, position.longitude);
Placemark p = place[0];
setState(() {
//userLocation = "${p.locality}, ${p.country}";
userLocation = Random().nextInt(10).toString();
print("A");
});
}).catchError((e) {
print("------------");
print(e);
print("------------");
});
},
),
Padding(
padding: EdgeInsets.all(10),
child: Center(child: Text("$userLocation"))),
Divider(),
FlatButton(
child: Text("Set sleep length"),
onPressed: () {
//TODO
},
),
Padding(
padding: EdgeInsets.all(10),
child: Center(child: Text("$sleepLength"))),
Divider(),
],
));
});
});
},
child: Icon(Icons.settings),
backgroundColor: Colors.black12,
);
}
}
Using StatefulBuilder
you can solve this problem
Replace your MyDialogState
with:
class MyDialogState extends State<MyDialog> {
String userLocation;
double sleepLength;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)
),
elevation: 20,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return ListView(
children: <Widget>[
FlatButton(
child: Text("Get location $userLocation"),
onPressed: () {
final Geolocator geolocator = Geolocator();
geolocator
.getCurrentPosition()
.then((Position position) async {
List<Placemark> place = await geolocator
.placemarkFromCoordinates(position.latitude, position.longitude);
Placemark p = place[0];
setState(() {
//userLocation = "${p.locality}, ${p.country}";
userLocation = Random().nextInt(10).toString();
print("A");
});
}).catchError((e) {
print("------------");
print(e);
print("------------");
});
},
),
Padding(
padding: EdgeInsets.all(10),
child: Center(child: Text("$userLocation"))
),
Divider(),
FlatButton(
child: Text("Set sleep length"),
onPressed: () {
//TODO
},
),
Padding(
padding: EdgeInsets.all(10),
child: Center(child: Text("$sleepLength"))
),
Divider(),
],
);
},
)
);
}
);
},
child: Icon(
Icons.settings
),
backgroundColor: Colors.black12,
);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.