I am using BottomNavigationBar to display a list of three menus. When user selects the Gallery I render a Stateful component that renders FutureBuilder in its build method. This works as expected, with the exception that when user navigates to another screen, Gallery widget is disposed off and thus I lose all of the images I just fetched. How do I cache them effectively?
home-page.dart widget:
final List<Widget> _menuOptions = <Widget>[
Text(
'Schedules',
style: optionStyle
),
Text(
'Stats',
style: optionStyle
),
GalleryPage(key: PageStorageKey('gallery'))
];
void _onMenuSelected(int index){
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context){
//...
body: Center(
child: _menuOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.schedule),
title: Text('Schedules'),
),
BottomNavigationBarItem(
icon: Icon(Icons.satellite),
title: Text('Stats'),
),
BottomNavigationBarItem(
icon: Icon(Icons.image),
title: Text('Gallery'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onMenuSelected,
)
gallery-page.dart widget:
class GalleryPage extends StatefulWidget {
GalleryPage({Key key}) : super(key: key);
@override
_GalleryPageState createState() => _GalleryPageState();
}
class _GalleryPageState extends State<GalleryPage> with AutomaticKeepAliveClientMixin {
Future<List<GalleryImage>> futureGalleryImages;
final AsyncMemoizer _memoizer = AsyncMemoizer();
@override
void deactivate() {
// TODO: implement deactivate
super.deactivate();
print('deactiveating');
}
@override
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_populateGalleryImages();
}
@override
Widget build(BuildContext context) {
super.build(context);
return FutureBuilder(
future: this.futureGalleryImages,
builder: (BuildContext context, AsyncSnapshot snapshot) {
//...
return _createListView(context, snapshot);
}
},
);
}
Future _populateGalleryImages() {
return this._memoizer.runOnce(() async {
this.futureGalleryImages = GalleryService().fetchGalleryImages();
});
}
Things I have tried:
Using the
AutomaticKeepAliveClientMixinmixin with thewantKeepAliveproperty set to true. This however doesn't work as my component always enters thedeactivelife cycle and is always disposed. The data fetching occurs every time. I was hoping to useAsyncMemoizerif the component did not get disposed.Using
PageStorageKeywhen instantiating the component as seen above. Did not work.
Any suggestions on what I am doing wrong?