导航到另一个pageView或任何其他View时,Bloc小部件reftech数据(重建)

时间:2020-06-08 20:28:06

标签: flutter widget bloc

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

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

如下图所示:

Screenshot that shows the problem

小部件树如下:

  • main.dart
    • home.dart
      • timeline.dart(屏幕截图中显示的屏幕)

尝试的解决方案::我将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,
                              )
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),


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

here是类timeline.dart的代码

here是包含home.dart类的类BottomNavigationBar的代码

问题:如何在每次重新构建窗口小部件时阻止集团获取数据?

2 个答案:

答案 0 :(得分:4)

我终于解决了这个问题 事实证明,这与bloc无关,而是与PageView相关的问题。

我将PageViewPageStorage小部件包装在一起,如下所示:

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,用于保存和恢复可能超出窗口小部件的值

感谢这篇出色的媒介文章,完美地解释了这一点: Keeping State with the Bottom Navigation Bar in Flutter

答案 1 :(得分:3)

您使用BlocProvider小部件的方式错误 相反,您应该将BlocProvider提取到较高的级别,而在页面“如果您在整个应用程序中使用此bloc的情况下,请从Maby到MaterialApp小部件”之间导航时,将不会重建该BlocProvider。 然后使用BlocBuilder或BlocConsumer将现有Bloc实例提供给子窗口小部件,并在bloc状态更改时自动重建。 BlocBuilder官方文档: https://bloclibrary.dev/#/flutterbloccoreconcepts?id=blocbuilder