Home > Back-end >  Flutter : Is there a way to make a gridview wait until I load all the data
Flutter : Is there a way to make a gridview wait until I load all the data

Time:05-06

I am reading from the local DB (SqlLite) and my gridview doesn't render when I press restart. However, when I do a hot reload the grid renders just fine with the data. I am guessing during the init since the data is still being loaded and the gridview doesn't wait. Is there any way I can manage that?

Here is my code.

class BookShelfList extends StatefulWidget {
  const BookShelfList({Key? key}) : super(key: key);

  @override
  State<BookShelfList> createState() => _BookShelfListState();
}

class _BookShelfListState extends State<BookShelfList> {
  late List<BookShelf> data = [];
 @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _getBooks();
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 300,
      child: Column(
        children: [
          Text("You have ${data.length} books "),
          Flexible(child: buildGridList(data)),
        ],
      ),
    );
  }
  Widget buildGridList(List<BookShelf> data) {
    return GridView.builder(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 1,
      ),
      itemCount: data.length,
      itemBuilder: (BuildContext context, index) {
        return Card(
          margin: EdgeInsets.all(5),
          child: GridTile(
              header: GridTileBar(
                backgroundColor: Colors.white,
                title: Text(
                  data[index].author,
                  style: TextStyle(color: Colors.black),
                ),
                subtitle: Text(data[index].dateAdded,
                    style: TextStyle(color: Colors.grey)),
                trailing: IconButton(
                    onPressed: () {},
                    icon: const Icon(
                      Icons.more_vert_rounded,
                      color: Colors.black54,
                    )),
              ),
              child: Image.network(
                data[index].thumbnail,
                height: 60,
                width: 70,
                fit: BoxFit.fill,
              ),
              footer: GridTileBar(
                backgroundColor: Colors.white,
                title: Row(
                  children: const [
                    Icon(
                      Icons.favorite_outline,
                      color: Colors.grey,
                    ),
                    Text('20', style: TextStyle(color: Colors.black)),
                    SizedBox(
                      width: 20,
                    ),
                    Icon(
                      Icons.chat_bubble_outline,
                      color: Colors.grey,
                    ),
                    Text(
                      '5',
                      style: TextStyle(color: Colors.black),
                    ),
                  ],
                ),
                trailing: const Icon(
                  Icons.bookmark_outline,
                  color: Colors.black,
                ),
              )),
        );
      },
    );
   _getBooks() async {
    data = await BookShelfDbProvider().fetchBook();
  }}

CodePudding user response:

Try calling setState() in _getBooks() right after the data = await BookShelfDbProvider().fetchBook();

CodePudding user response:

okay, so, Make Gridview.builder a child of future builder and pass future to _getBooks()

What happens is, while the _getBooks() function is running, you could show a CircularProgressBar, and as soon as the data is received, GridView.builderis triggered.

And calling _getBooks() in initState() is not necessary in this case.

Here's your updated code:

   _getBooks() async {
    data = await BookShelfDbProvider().fetchBook();
  }


class BookShelfList extends StatefulWidget {
  const BookShelfList({Key? key}) : super(key: key);

  @override
  State<BookShelfList> createState() => _BookShelfListState();
}

class _BookShelfListState extends State<BookShelfList> {
  late List<BookShelf> data = [];

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 300,
      child: Column(
        children: [
          Text("You have ${data.length} books "),
          Flexible(child: buildGridList(data)),
        ],
      ),
    );
  }
  Widget buildGridList(List<BookShelf> data) {
    return FutureBuilder(
      future: _getBooks(),
      builder: (context, snapshot){
        
        if(snapshot!=null){
          return GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 1,
        ),
        itemCount: data.length,
        itemBuilder: (BuildContext context, index) {
          return Card(
            margin: EdgeInsets.all(5),
            child: GridTile(
                header: GridTileBar(
                  backgroundColor: Colors.white,
                  title: Text(
                    data[index].author,
                    style: TextStyle(color: Colors.black),
                  ),
                  subtitle: Text(data[index].dateAdded,
                      style: TextStyle(color: Colors.grey)),
                  trailing: IconButton(
                      onPressed: () {},
                      icon: const Icon(
                        Icons.more_vert_rounded,
                        color: Colors.black54,
                      )),
                ),
                child: Image.network(
                  data[index].thumbnail,
                  height: 60,
                  width: 70,
                  fit: BoxFit.fill,
                ),
                footer: GridTileBar(
                  backgroundColor: Colors.white,
                  title: Row(
                    children: const [
                      Icon(
                        Icons.favorite_outline,
                        color: Colors.grey,
                      ),
                      Text('20', style: TextStyle(color: Colors.black)),
                      SizedBox(
                        width: 20,
                      ),
                      Icon(
                        Icons.chat_bubble_outline,
                        color: Colors.grey,
                      ),
                      Text(
                        '5',
                        style: TextStyle(color: Colors.black),
                      ),
                    ],
                  ),
                  trailing: const Icon(
                    Icons.bookmark_outline,
                    color: Colors.black,
                  ),
                )),
          );
        },
      );
        } else {
          return CircularProgressIndicator();
        }
        
      }
    );

Please adjust the {}'s as necessary.

Hope it Helps :), please upvote if it does.

  • Related