I have a ListView inside a bottomSheet, that is built using an array of elements. Currently I have one item in there "empty" which is then .clear()
ed and populated after an async DB call.
The variable update is correct, and I try to use setState((){})
but the ListView isn't updated at all. I need to close the bottomSheet, reopen it, and the ListView then has the correct items.
Do I need to just call setState
or does the bottomSheet builder need to be flagged to update?
Main ListView section:
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My Map'),
backgroundColor: Colors.green[700],
),
//Put in a stack widget so can layer other widgets on top of map widget
body: Stack(
children: <Widget>[
GoogleMap(
mapType: _currentMapType,
markers: _markers,
onMapCreated: _onMapCreated,
onCameraMove: _onCameraMove,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
SizedBox(width: 16.0),
Builder(
builder: (context) => FloatingActionButton(
...
),
),
SizedBox(width: 16.0),
FloatingActionButton(
...
),
SizedBox(width: 16.0),
Builder(
builder: (context) => FloatingActionButton(
child: Icon(Icons.file_download, size: 36.0),
backgroundColor: Colors.green,
onPressed: () {
showBottomSheet(
context: context,
builder: (context) {
return ListView(
padding: EdgeInsets.all(15.0),
children: <Widget>[
...
Divider(),
ListTile(
title: Text("Remote JSON Download"),
trailing:
Icon(Icons.refresh),
selected: true,
onTap: _OnPressedReloadJSON, <-------------
),
Divider(),
Container(
height: 150.0,
child: ListView.builder( <-------------
scrollDirection: Axis.horizontal,
itemCount : testList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.all(5.0),
margin: EdgeInsets.all(5.0),
width: 150.0,
color: Colors.red,
child: Text(testList[index]),
);
},
),
),
Async Get:
class _MyAppState extends State<MyApp> {
...
_OnPressedReloadJSON() {
fetchJSONAndMakeListTile();
}
...
List<String> testList= ["empty"];
Future<http.Response> fetchJSONAndMakeListTile() async {
final response = await http.get('https://..... file.json');
// If the server did return a 200 OK response, then parse the JSON.
if (response.statusCode == 200) {
List<db_manager.MyObject> myObjects = (json.decode(response.body) as List)
.map((e) => db_manager.MyObject.fromJson(e))
.toList();
testList.clear();
myObjects.forEach((db_manager.MyObject al) {
testList.add(al.code);
print("debug:"+al.code+" - "+al.name); <------------- prints correctly
});
//TODO Does this even work?
//Trigger update of state - ie redraw/reload UI elements
setState(() {});
} else {
// If the server did not return a 200 OK response, then throw an exception.
print(response);
throw Exception('Failed to load json');
}
}
UPDATE:
I've abstracted the BottomSheet builder into another class (as per another answer) as its own StatefulWidget but I can't seem to access the void onPress()
method from my main dart file. If the BottomSheet creation/builder is in this separate dart file, how do I call it to build and then update its state with the async
call updating the listview contents List?
BottomSheetWidget.dart
class BottomSheetDatabases extends StatefulWidget {
@override
_BottomSheetDatabases createState() => _BottomSheetDatabases();
}
class _BottomSheetDatabases extends State<BottomSheetDatabases> {
void _onpress() {
}
void loadMe() {
}
List<String> testList= ["empty"];
@override
Widget build(BuildContext context) {
return BottomSheet(
builder: (context) {
return ListView(
padding: EdgeInsets.all(15.0),
children: <Widget>[
ListTile(
...
),
Divider(),
Container(
height: 150.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: testList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
key: UniqueKey(),
//TODO ??
padding: EdgeInsets.all(5.0),
margin: EdgeInsets.all(5.0),
width: 150.0,
color: Colors.red,
child: Text(testList[index]),
);
},
),
//),
//),
),
...
Main.dart:
void _loadSheetDatabases() {
BottomSheetWidget bottomSheetwidget = BottomSheetWidget();
bottomSheetwidget.loadMe();
}
Seems to me that a Key
are missing into widget that ListView.Builder returns, try to put a UniqueKey()
or ValueKey into Container or Text:
Container(
key: UniqueKey(),
padding: EdgeInsets.all(5.0),
margin: EdgeInsets.all(5.0),
width: 150.0,
color: Colors.red,
child: Text(testList[index]),
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With