This is my first attempt at a Flutter app after Swift/Android, and having trouble getting data to display on first run of the app.
In my list screen, I build a list using GroupedListView and all is ok if I load a local json file as the datasource, but if I instead pull the exact same data from Hive, the list is shown empty on first run and only shows after hot restart. Can't see where I am going wrong. In the below code readJson() works but getData() does not.
class venueList extends StatefulWidget {
const venueList({Key? key}) : super(key: key);
@override
State<venueList> createState() => _venueList();
}
class _venueList extends State<venueList> {
List<Venue> _venues = [];
@override
void initState() {
super.initState();
//readJson();
getData();
}
// This works
// Future<void> readJson() async {
// final String response = await rootBundle.loadString('assets/venues.json');
// final data = await json.decode(response);
// setState(() {
// _venues = data["items"];
// });
// }
// This doesn't
Future<void> getData() async {
final venueBox = await Hive.openBox('venuesBox');
setState(() {
_venues = List<Venue>.from(venuesBox.values.toList());
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GroupedListView<Venue, String>(
elements: _venues,
groupBy: (Venue v) => v.venueGroup,
groupComparator: (value1, value2) => value2.compareTo(value1),
order: GroupedListOrder.DESC,
useStickyGroupSeparators: true,
separator: Divider(
height: 1.0,
color: Colors.grey,
),
groupSeparatorBuilder: (String value) => Padding(
padding: const EdgeInsets.all(0.0),
child: Container(
padding: const EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 15.0),
color: kMidBlueColour,
child: Text(
value.toUpperCase(),
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.normal,
fontFamily: 'SanFranciscoDisplay',
color: Colors.white),
),
),
),
itemBuilder: (c, Venue v) {
return ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
leading: Hero(
tag: v.venueName,
child: Container(
child: Image.asset(
'images/venue1440/' v.venueImage,
fit: BoxFit.contain,
),
),
),
title: Text(
v.venueTitle.toString().toUpperCase(),
style: TextStyle(
color: kMidBlueColour,
fontFamily: 'SanFranciscoDisplay',
fontSize: 20.0,
),
),
subtitle: Text(
v.venueAddress,
style: TextStyle(
color: Color(0xFF4A4A49),
fontFamily: 'SanFranciscoDisplay',
fontSize: 18.0,
),
),
trailing: const Icon(
Icons.circle,
color: Colors.grey,
size: 50.0,
),
visualDensity: const VisualDensity(horizontal: 4, vertical: 0),
onTap: () {
},
);
},
),
);
}
}
CodePudding user response:
You have to use FutureBuilder. refer this article.