我正在使用
BottomNavigationBar
显示三个菜单的列表。当用户选择 Gallery
时,我渲染一个 Stateful
组件,该组件在其 FutureBuilder
方法中渲染 build
。这按预期工作,但当用户导航到另一个屏幕时,Gallery
小部件被处理掉,因此我丢失了刚刚获取的所有图像。如何有效地缓存它们?
home-page.dart
小部件:
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
小部件:
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();
});
}
我尝试过的事情:
使用
AutomaticKeepAliveClientMixin
mixin 并将 wantKeepAlive
属性设置为 true。然而,这不起作用,因为我的组件总是进入 deactive
生命周期并且总是被处置。每次都会发生数据获取。如果组件没有被处置,我希望使用 AsyncMemoizer
。在实例化组件时使用
PageStorageKey
,如上所示。没成功。对我做错了什么有什么建议吗?
您可以使用riverpod来缓存数据。
@Riverpod(keepAlive: true)
Future<List<GalleryImage>> galleryImages(GalleryImagesRef ref) async{
return GalleryService().fetchGalleryImages();
}
并在构建方法中使用它,例如:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Test extends ConsumerWidget {
const Test({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final galleryImages = ref.watch(galleryImagesProvider);
return galleryImages.whenData(() => _createListView(context));
}
}