简体   繁体   English

Flutter BLoC 模式 - 如何在流事件后导航到另一个屏幕?

[英]Flutter BLoC pattern - How can I navigate to another screen after a stream event?

My question is about navigation used with the BLoC pattern .我的问题是关于与BLoC 模式一起使用的导航

In my LoginScreen widget I have a button that adds an event into the EventSink of the bloc.在我的 LoginScreen 小部件中,我有一个按钮可以将事件添加到集团的 EventSink 中。 The bloc calls the API and authenticates the user.该集团调用 API 并对用户进行身份验证。 Where in the LoginScreen Widget do I have to listen to the stream, and how do I navigate to another screen after it returns a success status?我必须在 LoginScreen 小部件中的哪个位置收听流,以及在返回成功状态后如何导航到另一个屏幕?

Use BlockListener .使用BlockListener

 BlocListener(
  bloc: _yourBloc,
  listener: (BuildContext context, YourState state) {
    if(state is NavigateToSecondScreen){
      Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {return SecondScreen();}));
    }
  },
  child: childWidget
)

The navigator is not working in blocBuilder, because in blocBuilder, you can only return a widget导航器在 blocBuilder 中不起作用,因为在 blocBuilder 中,您只能返回一个小部件

But BlocListener solved it for me.但是 BlocListener 为我解决了它。

Add this code:添加此代码:

BlocListener(
  bloc: _yourBloc,
  listener: (BuildContext context, YourState state) {
    if(state is NavigateToSecondScreen){
      Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {return SecondScreen();}));
    }
  },
  child: childWidget
)

First of all: if there isn't any business logic, then there isn't any need to go to YourBloc class.首先:如果没有任何业务逻辑,那么就没有必要去 YourBloc 类。

But from time to time some user's activity is required to perform some logic in Bloc class and then the Bloc class has to decide what to do next: just rebuild widgets or show dialog or even navigate to next route .但是有时需要一些用户的活动来执行Bloc类中的一些逻辑,然后 Bloc 类必须决定下一步做什么:只需重建小部件显示对话框,甚至导航到下一条路线 In such a case, you have to send some State to UI to finish the action.在这种情况下,您必须向 UI 发送一些状态才能完成操作。

Then another problem appears: what shall I do with widgets when Bloc sends State to show a toast?然后另一个问题出现了:当 Bloc 发送 State 来显示 toast 时,我应该如何处理小部件?

And this is the main issue with all of this story.这是所有这个故事的主要问题。

A lot of answers and articles recommend to use flutter_block .很多答案和文章都推荐使用flutter_block This library has BlocBuilder and BlocListener .这个库有BlocBuilderBlocListener With those classes you can solve some issues, but not 100% of them.使用这些类,您可以解决一些问题,但不是 100%。

In my case I used BlocConsumer which manages BlocBuilder and BlocListener and provides a brilliant way to manage states.在我的例子中,我使用了BlocConsumer ,它管理BlocBuilderBlocListener并提供了一种管理状态的绝妙方法。

From the documentation:从文档:

BlocConsumer<BlocA, BlocAState>(
  listenWhen: (previous, current) {
    // Return true/false to determine whether or not
    // to invoke listener with state
  },
  listener: (context, state) {
    // Do stuff here based on BlocA's state
  },
  buildWhen: (previous, current) {
    // Return true/false to determine whether or not
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // Return widget here based on BlocA's state
  }
)

As you can see with BlocConsumer , you can filter states: you can easily define states to rebuild widgets and states to show some popups or navigate to the next screen.正如您在BlocConsumer中看到的,您可以过滤状态:您可以轻松定义状态以重建小部件和状态以显示一些弹出窗口或导航到下一个屏幕。

Something like this:像这样的东西:

if (state is PhoneLoginCodeSent) {
    // Dispatch here to reset PhoneLoginFormState
    SchedulerBinding.instance.addPostFrameCallback((_) {
        Navigator.of(context).push(
            MaterialPageRoute(
                builder: (context) {
                    return VerifyCodeForm(phoneLoginBloc: _phoneLoginBloc);
                },
            ),
        );
        return;
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM