使用 BottomNavigationBar 时如何通过屏幕导航缓存 FutureBuilder 异步结果?

问题描述 投票:0回答:1

我正在使用

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

我尝试过的事情:

  1. 使用

    AutomaticKeepAliveClientMixin
    mixin 并将
    wantKeepAlive
    属性设置为 true。然而,这不起作用,因为我的组件总是进入
    deactive
    生命周期并且总是被处置。每次都会发生数据获取。如果组件没有被处置,我希望使用
    AsyncMemoizer

  2. 在实例化组件时使用

    PageStorageKey
    ,如上所示。没成功。

对我做错了什么有什么建议吗?

flutter
1个回答
0
投票

您可以使用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));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.