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.builder
is 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.