在Flutter Bloc中管理onBackPressed的状态

时间:2019-11-03 10:51:59

标签: flutter bloc

所以我有一个可单击的简单列表,然后转到DetailScreen,我遇到的问题是当我从DetailScreen单击时,如何管理此状态以保存最后一个列表?

集团

if (event is GetNews && !_hasReachedMax(state)) {
      try {
        if (currentState is NewsInitial) {
          final news = await fetchNews(event.cat, pageNumber);
          yield NewsLoaded(news, false);
        }
        if (currentState is NewsLoaded) {
          pageNumber++;
          final news = await fetchNews(event.cat, pageNumber);
          yield news.isEmpty
              ? currentState.copyWith(hasReachedMax: true)
              : NewsLoaded(currentState.node + news, false);
        }
      } catch (error) {
        print(error);
        yield NewsError("Error fetching news" + error);
      }
    } else if (event is GetDetailedNews) {
      try {
        final filter = await fetchDetailedNews(event.id);
        yield DetailedNewsLoaded(filter);
      } catch (error) {
        yield NewsError("Couldn't fetch news : $error");
      }
    }

将事件附加到集团

  @override
  void initState() {
    super.initState();
    _postBloc = BlocProvider.of<NewsBloc>(context)
      ..add(GetNews(widget.cat));
  }

BlocBuilder

OnBackPressed因为我不知道如何管理状态,所以我只能坚持使用else

    return BlocBuilder<NewsBloc, NewsState>(builder: (context, state) {
      if (state is NewsLoaded) {
          return ListView.builder(
              controller: _scrollController,
              itemCount: state.hasReachedMax
                  ? state.node.length
                  : state.node.length + 1,
              itemBuilder: (context, index) {
                fullList = state.node;
                print("list: ${state.node} \nlength: ${state.node
                    .length} \nindex: $index \n--------------");
                return index >= state.node.length ?
                BottomLoader() :
                listViews(context, state.node[index], index);
              });
      }
      else if (state is NewsError) {
          return Center(
              child: Container(
                child: Text(state.message),
              ));
      }
      else {
        return Center(child: CircularProgressIndicator(),);
      }
    });

状态

abstract class NewsState extends Equatable {
  const NewsState();

  @override
  List<Object> get props => [];
}

class NewsInitial extends NewsState {
  const NewsInitial();

  @override
  List<Object> get props => [];
}

class NewsLoading extends NewsState {
  const NewsLoading();

  @override
  List<Object> get props => [];
}
class NewsLoaded extends NewsState {
  final List<Node> node;
  final bool hasReachedMax;

  NewsLoaded(this.node, this.hasReachedMax);

  NewsLoaded copyWith({List<Node> node, bool hasReachedMax}) {
    return NewsLoaded(node ?? this.node, hasReachedMax ?? this.hasReachedMax);
  }

  @override
  List<Object> get props => [node];
}

class DetailedNewsLoaded extends NewsState {
  final List<Node> node;

  DetailedNewsLoaded(this.node);

  @override
  List<Object> get props => [node];
}
}

在详细信息屏幕中,我添加了GetDetailScreen事件,该事件在onBackPressed时保持不变

  @override
  void initState() {
    BlocProvider.of<NewsBloc>(context)
      ..add(GetDetailedNews(widget.id));
    super.initState();
  }

2 个答案:

答案 0 :(得分:1)

我认为问题在于,当您按此按钮查看文章时,您的状态更改为DetailedNewsLoaded。因此,当您按回退时,BlocBuilder<NewsBloc, NewsState>进入else状态,该状态返回CircularProgressIndicator

据您所知,您不需要DetailedNewsLoaded状态。您只需要将state.node作为简单参数传递给DetailsScreen

答案 1 :(得分:0)

在Flutter中已经拥有hero widget时,为什么要做很多事情。

  1. 列出清单。
  2. 将Hero动画用于列表项及其详细信息视图。
  3. 每当单击列表项时,都会显示详细信息视图。
  4. 当用户按下“后退”按钮时,他/她将到达该特定列表项所在的位置。

因此,基本上您不需要太多。

我正在研究一些项目,并在github上找到了它:https://github.com/whatsupcoders/Flutter-Hero-Widget

此项目在我在YouTube上发现的以下视频中得到了介绍:https://www.youtube.com/watch?v=mgSB5r11_Xw&t=15s

该项目使用Hero小部件,希望对您有所帮助。