Flutter Bloc Pattern - 如何在流事件后导航到另一个屏幕?

Seb*_*ian 14 dart dart-async reactive-streams flutter

我的问题是关于与集团模式一起使用的导航.

在我的LoginScreen小部件中,我有一个按钮,可以将事件添加到集团的EventSink中.bloc调用API并验证用户身份.问题是在LoginScreen Widget中我必须监听流,以及在返回成功状态后如何导航到另一个屏幕.

希望我清楚自己.谢谢!

小智 8

使用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
)
Run Code Online (Sandbox Code Playgroud)


hos*_*ein 7

导航器在 blocBuilder 中不起作用,因为在 blocBuilder 中,您只能返回一个小部件

但是 BlocListener 为我解决了它。

添加此代码:

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


Vol*_*kiv 5

首先:如果没有任何业务逻辑,则不需要转到 YourBloc 类。

但有时需要某些用户的活动来执行Bloc类中的某些逻辑,然后 Bloc 类必须决定下一步要做什么:只是重建小部件显示对话框,甚至导航到下一个路线。在这种情况下,您必须向 UI 发送一些状态才能完成操作。

那么另一个问题出现了:当 Bloc 发送 State 来显示 toast 时,我该如何处理 widget?

这是整个故事的主要问题。

很多答案和文章推荐使用flutter_block。该库有BlocBuilderBlocListener。通过这些课程,您可以解决一些问题,但不是 100%。

就我而言,我使用了BlocConsumer,它管理BlocBuilderBlocListener,并提供了一种管理状态的绝妙方法。

从文档中:

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
  }
)
Run Code Online (Sandbox Code Playgroud)

正如您在BlocConsumer中看到的,您可以过滤状态:您可以轻松定义状态来重建小部件和状态以显示一些弹出窗口或导航到下一个屏幕。


小智 0

像这样的东西:

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