在tabBarView页面中使用导航器后,数据丢失

时间:2019-04-03 12:25:45

标签: flutter navigator

我有一个带有tabBarView的主页,其中包含2页,分别是首页和收藏夹。主页上有一个gridview,其单元格由streambuilder填充。单击时,他们使用导航器重定向到该单元格的详细信息页面。我可以在2个标签页之间切换。转到详细信息页面(从主页)并返回首页后,gridView会正确显示其数据。但是之后,如果我转到“收藏夹”页面并返回首页,则gridView数据将丢失。

我已经按照SO的建议尝试了AutomaticKeepAliveClientMixinwantKeepAlive = true

根据调试器的显示,首页小部件在与收藏夹之间切换时不会重建,并且数据显示正常。

从详细信息页面返回主页确实会重建主页,这在数据显示时也可以。只有在那之后我转到“收藏夹”选项卡并再次返回时,问题才会发生。

我正在使用Bloc模式,并且在主窗口小部件中引用了提供者的bloc。它将其传递给gridView

我在SliverAppBar中使用标准的tabBarView和Navigator。


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MovieProvider(
      euCollBloc: EuThemeCollectionBloc(API()),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(),

        home: MyHomePage(),
      ),
    );
  }
}


body: TabBarView(
          children: <Widget>[
            PageOne(),

            PageTwo(),

          ],

bottom: TabBar(
                  tabs: <Widget>[
                    Tab(
                      text: "Home",
                      icon: Icon(Icons.home),
                    ),
                    Tab(
                      text: "Favorites",
                      icon: Icon(Icons.favorite),
                    ),

                  ],
                  controller: _tabController,
                ))

.......

导航器,在PageOne小部件中使用:

.......

return GridView.builder(
              gridDelegate:
                  SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
              itemCount: snapshot.data.length,
              itemBuilder: (context, index) => GestureDetector(
                    onTap: () {
                      Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) => EuroCard(
                              preview: snapshot.data[index].preview ?? "",
                              title: snapshot.data[index].title,
                              description: snapshot.data[index].description,
                            ),
                      ));
                    },
                    child: Card(
.......

使用tensor在youtube上的教程中的提供程序和bloc代码(对我来说可能太高级了。)

集团:

class EuThemeCollectionBloc {
  final API api;

  Stream<List<EuThemeCollection>> _results = Stream.empty();
  Stream<String> _log = Stream.empty();

  ReplaySubject<String> _query = ReplaySubject<String>();

  Stream<String> get log => _log;
  Stream<List<EuThemeCollection>> get results => _results;
  Sink<String> get query => _query;

  EuThemeCollectionBloc(this.api) {
    _results = _query.distinct().asyncMap(api.get).asBroadcastStream();

    _log = Observable(results)
        .withLatestFrom(_query.stream, (_, query) => 'Results for $query')
        .asBroadcastStream();
  }

  void dispose() {
    _query.close();
  }
}


提供者:

class MovieProvider extends InheritedWidget {
  final EuThemeCollectionBloc euCollBloc;

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;

  static EuThemeCollectionBloc of(BuildContext context) =>
      (context.inheritFromWidgetOfExactType(MovieProvider) as MovieProvider)
          .euCollBloc;

  MovieProvider({Key key, EuThemeCollectionBloc euCollBloc, Widget child})
      : this.euCollBloc = euCollBloc ?? EuThemeCollectionBloc(API()),
        super(child: child, key: key);
}

我尝试使用BehaviorSubject,但随后出现运行时错误,该错误指向主页中的查询流:

错误:未为类“ EuroCard”定义吸气剂“ euCollBloc”。  -“ EuroCard”来自“ package:bloc_example / euroCard.dart”(“ lib / euroCard.dart”)。 尝试将名称更正为现有吸气剂的名称,或者定义一个名为“ euCollBloc”的吸气剂或字段。

已修复: 我需要将super.build(context)添加到PageOne(GridView)小部件-它正在使用AutomaticKeepAliveClientMixin扩展State,因此需要重写。抱歉,原来根本没有张贴罪魁祸首。


class _PageOneState extends State<PageOne>  with
AutomaticKeepAliveClientMixin<PageOne>{
  @override
  bool get wantKeepAlive => true;
  Widget build(BuildContext context){
   super.build(context);
  var euCollBloc = MovieProvider.of(context);






1 个答案:

答案 0 :(得分:0)

我似乎已经通过PageOne(GridView)小部件中的简单setState((){euCollBloc = euCollBloc)}修复了该问题。

我现在可以做我以前做不到的事情:加载显示带有数据单元格的Gridview的主页选项卡,然后导航到单元格详细信息页面并返回主页,切换到收藏夹页面,然后再次回到主页,并且数据仍然显示。

关于此问题的修复原因,我不确定。我认为Provider模式可以防止这样的setStates。