Flutter:有没有办法让 gridview 等到我加载所有数据

Flutter : Is there a way to make a gridview wait until I load all the data

我正在从本地数据库 (SqlLite) 读取数据,但当我按下重新启动时我的 gridview 没有呈现。但是,当我进行热重载时,网格可以很好地处理数据。我在初始化期间猜测,因为数据仍在加载并且 gridview 不等待。有什么办法可以解决吗?

这是我的代码。

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();
  }}

尝试在 data = await BookShelfDbProvider().fetchBook();

之后立即在 _getBooks() 中调用 setState()

Gridview.builder成为未来建设者的child,并将未来传给_getBooks()

发生的事情是,当 _getBooks() 函数是 运行 时,您可以显示一个 CircularProgressBar,并且一旦接收到数据,就会触发 GridView.builder .

在这种情况下,在 initState() 中调用 _getBooks() 是没有必要的。

这是您的更新代码:

   _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();
        }
        
      }
    );

请根据需要调整 {}