首页 > 解决方案 > 导航到另一个 pageView 或任何 View 时,Bloc 小部件 reftech 数据(重建)

问题描述

上下文:我有一个应用程序可以PageView在五个屏幕之间导航BottomNavigationBar,其中一个页面正在使用 Bloc 模式(在未来的版本中几乎所有页面都将使用 Bloc)这些 Blocs 正在从后端服务获取数据以填充 UI与获取的数据。

问题:在小部件树的任何级别的页面之间导航时。Bloc 小部件“重置”并从存储库中重新获取数据。

如下图所示:

显示问题的屏幕截图

小部件树如下:

尝试过的解决方案:我将其添加AutomaticKeepAliveClientMixin到页面类和其他页面,但它没有完成这项工作。

这是上面屏幕截图中显示的页面的构建方法的代码

   @override
  Widget build(BuildContext context) {

    super.build(context);

    return DefaultTabController(
      length: 4,
      child: Scaffold(
        backgroundColor: Colors.white,
        appBar: _builAppBarWithTabs(),
        body: Center(
          child: ConstrainedBox(
            constraints: BoxConstraints(maxWidth: 1200),
            child: ListView(
              scrollDirection: Axis.vertical,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(bottom: 150),
                  child: Container(
                    height: 800,
                    child: CustomScrollView(
                      scrollDirection: Axis.vertical,
                      slivers: <Widget>[
                        SliverToBoxAdapter(
                          child: MasonryGrid(
                            column: getResponsiveColumnNumber(context, 1, 2, 6),
                            children: <Widget>[
                              // First Bloc
                              BlocProvider(
                                create: (context) {
                                  BrandBloc(repository: _brandRepository);
                                },
                                child: Container(
                                  width: 200,
                                  alignment: Alignment.center,
                                  height: 80,
                                  child: BrandScreen(
                                    brandBloc: context.bloc(),
                                  ),
                                ),
                              ),
                              CategoryScreen(
                                // Second Bloc
                                categoryBloc: CategoryBloc(
                                  repository: context.repository(),
                                ),
                              ),
                              Container(
                                width: 200,
                                alignment: Alignment.center,
                                height: 330,
                                child: _buildFeaturedItemsList(),
                              ),
                              Placeholder(
                                strokeWidth: 0,
                                color: Colors.white,
                              )
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),


              ],
            ),
          ),
        ),
      ),
    );
  }

是类的代码timeline.dart

home.dart包含该类的BottomNavigationBar类的代码

问题:如何在每次小部件重建时阻止块获取数据?

标签: flutterwidgetbloc

解决方案


我终于明白了这个问题事实证明,这bloc与问题无关PageView

PageView我将with小部件包装PageStorage如下:

final PageStorageBucket bucket = PageStorageBucket(); //PageStorageBucket
  static List<Widget> pages = [
    Timeline(pageController: pageController, key: PageStorageKey('timeline')),
    Search(key: PageStorageKey('search')),
    LikeScreen(key: PageStorageKey('like')),
    CartScreen(key: PageStorageKey('cart')),
    storageService.getFromDisk('api_token') != null
        ? ProfileScreen(key: PageStorageKey('profile'))
        : AuthChooserScreen(key: PageStorageKey('auth')),
  ];
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return SafeArea(
      top: true,
      bottom: true,
      child: Scaffold(
        backgroundColor: Colors.white,
        key: _scaffoldKey,
        //Wrapped  PageView with PageStorage
        body: PageStorage(
          bucket: bucket,
          child: PageView(
            children: pages,
            controller: pageController,
            onPageChanged: onPageChanged,
            physics: NeverScrollableScrollPhysics(),
          ),
        ),
        bottomNavigationBar: _buildBottomNavigationBar(),
      ),
    );
  }

每个页面都分配有一个 PageStorageKey,用于保存和恢复可以超过小部件的值

感谢这篇很好的中篇文章,它完美地解释了它: 在 Flutter 中使用底部导航栏保持状态


推荐阅读