Home > OS >  Issue with setState and Hive
Issue with setState and Hive

Time:06-24

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.

  • Related