Reputation: 746
This is that builder which i just want to load once. I'm using a bottom navigation bar and this widget is in one of the tab; and as i switch between tabs this widget rebuilds. This widget doesn't rebuilds when i press on a grid tile and goes to the detail screen and come back to. It only rebuilds when i am switching between tabs.
class PostGridScreen extends StatefulWidget {
@override
_PostGridScreenState createState() => _PostGridScreenState();
}
class _PostGridScreenState extends State<PostGridScreen> {
@override
void initState() {
Future.delayed(Duration.zero).then((value) =>
Provider.of<BaseProvider>(context, listen: false).getPosts());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Claw Shop"),
centerTitle: true,
),
body: FutureBuilder(
future: Provider.of<BaseProvider>(context).getPosts(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text("Loading..."),
);
} else {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ItemGridTile();
});
}
}),
);
}
}
Upvotes: 0
Views: 469
Reputation: 579
You could try using the AutomaticKeepAliveClientMixin
. This will prevent the widget from being destroyed. You override the wantKeepAlive to choose when you want the widget to be destroyed. Below will always keep the widget alive. I have also moved the future to a class field so that it is not called in the build method (which can happen multiple times).
@override
bool get wantKeepAlive => true;
Note: you must call the super.build(context) with this mixin.
Edit: try making sure you are only building when connection state is done. You could also add other if else statements for other connection states.
class PostGridScreen extends StatefulWidget {
@override
_PostGridScreenState createState() => _PostGridScreenState();
}
class _PostGridScreenState extends State<PostGridScreen> with AutomaticKeepAliveClientMixin {
Future _getPosts;
@override
void initState() {
_getPosts = Provider.of<BaseProvider>(context, listen: false).getPosts();
super.initState();
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: AppBar(
title: Text("Claw Shop"),
centerTitle: true,
),
body: FutureBuilder(
future: _getPosts,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ItemGridTile();
});
} else {
return Center(
child: Text("Loading..."),
);
}
}),
);
}
@override
bool get wantKeepAlive => true;
}
Upvotes: 2