Navigation 集团、颤振与航行

Navigation 集团、颤振与航行,navigation,flutter,bloc,Navigation,Flutter,Bloc,所以,和大多数人一样,我是新加入阵营的,我会飞,会飞,会绕着头。我在谷歌上搜索过,浏览过这里的帖子,但没有找到任何答案 因此,这是关于使用bloc和Flatter的导航。以登录为例。所以有一个登录页面,后面有一个bloc,在某个点上有人按下按钮登录 因此,我们可以在执行验证的组中调用一个函数。我认为这是违反严格的方法,但我看到人们这样做。但是,如果登录成功,您如何导航到下一个屏幕?你不应该在一个集团里航行 但是,如果登录页面使用StreamBuilder更改状态,那么您也不能在builder中添

所以,和大多数人一样,我是新加入阵营的,我会飞,会飞,会绕着头。我在谷歌上搜索过,浏览过这里的帖子,但没有找到任何答案

因此,这是关于使用bloc和Flatter的导航。以登录为例。所以有一个登录页面,后面有一个bloc,在某个点上有人按下按钮登录

因此,我们可以在执行验证的组中调用一个函数。我认为这是违反严格的方法,但我看到人们这样做。但是,如果登录成功,您如何导航到下一个屏幕?你不应该在一个集团里航行

但是,如果登录页面使用StreamBuilder更改状态,那么您也不能在builder中添加导航,可以吗?您不能返回导航,而是返回小部件

initstate是您可以导航的地方,但是您可以在initstate中有一个流生成器来侦听bloc中的状态更改吗

现在一切都有点混乱,但我坚持下去,因为这应该是前进的方向

谢谢
保罗

要让集团是前进之路的神话彻底消失:没有完美的方式来处理国家。 每个状态管理架构都比其他架构更好地解决了一些问题;在决定体系结构时,始终存在权衡,了解这些权衡是很重要的

一般来说,好的体系结构是实用的:它具有可伸缩性和可扩展性,同时只需要最小的开销。 由于人们对实用性的看法不同,架构总是涉及到意见,因此,请恕我直言,因为我将阐述我个人对如何为您的应用程序采用BLoC的看法

BLoC是一种非常有前途的状态管理方法,因为它有一个标志性的成分:流。 它们允许将UI与业务逻辑分离,并且可以很好地使用Flutter-ish方法,即在组件子树过时后重新构建整个组件子树。 所以很自然地,集团之间的每一次交流都应该使用流,对吗

+----+  Stream   +------+
| UI | --------> | BLoC |
|    | <-------- |      |
+----+   Stream  +------+
这里,对于“活动”的数据和
Future
s作为方法调用的答案,BLoC返回
Stream
s

让我们看看你的例子是如何实现的:

  • 该集团可以提供用户是否登录的
    ,甚至可以提供来自谷歌I/O的
    流会话

    编辑:刚在中找到此体系结构,它被称为“简单集团”。如果你想了解不同的体系结构,我真的建议你看看回购协议


    当试图为一个BLoC操作提供多个参数时,它会变得更加丑陋,因为这样您就需要定义一个包装类来将其传递给流


    ²我承认,启动应用程序时会有点难看:你需要某种启动屏幕,它只检查集团的流,并根据用户是否登录将用户重定向到适当的屏幕。这个规则的例外是因为用户执行了一个操作——启动应用程序——但颤振框架不允许我们直接连接到该操作中(至少不优雅,据我所知)。BlocListener
    是您可能需要的小部件。如果状态更改为(例如)
    loginsucess
    ,则块侦听器可以调用通常的
    Navigate.of(context)
    。你可以找到一个

    另一个选项是向事件传递回调

     BlocProvider.of<MyBloc>(context).add(MyEvent(
                  data: data,
                  onSuccess: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) {
                        return HomePage();
                      }),
                    );
                  }));
    
    BlocProvider.of(context).add(MyEvent(
    数据:数据,
    成功:(){
    导航器。推(
    上下文
    MaterialPage路线(生成器:(上下文){
    返回主页();
    }),
    );
    }));
    
    首先:如果没有业务逻辑,那么就不需要去YourBloc类

    但有时,一些用户的活动需要在Bloc类中执行一些逻辑,然后Bloc类必须决定下一步要做什么:只需重建小部件显示对话框或甚至导航到下一个路径。在这种情况下,您必须向UI发送一些状态,以完成操作。 然后出现了另一个问题:当Bloc发送状态以显示toast时,我应该如何处理小部件

    这是整个故事的主要问题

    许多答案和文章推荐使用。这个图书馆有和。使用这些类,您可以解决一些问题,但不能100%解决

    在我的例子中,我使用了管理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
      }
    )
    
    BlocConsumer(
    listenWhen:(上一个,当前){
    //返回true/false以确定是否
    //使用状态调用侦听器
    },
    侦听器:(上下文、状态){
    //根据BlocA的状态在这里做事
    },
    buildWhen:(上一个,当前){
    //返回true/false以确定是否
    //使用状态重新生成小部件
    },
    生成器:(上下文、状态){
    //根据BlocA的状态在此处返回小部件
    }
    )
    

    正如您通过BlocConsumer所看到的那样,您可以过滤状态:您可以轻松定义状态以重建小部件,并定义状态以显示一些弹出窗口或导航到下一个屏幕

    正如felangel在Github中所提到的,我们可以使用BlocListner来实现这一目的

    BlocListener(
    bloc:BlocProvider.of(上下文),
    侦听器:(构建上下文,数据状态){
    如果(状态为成功){
    Navigator.of(context.pushNamed('/details');
    }              
    },
    孩子:BlocBuilder(
    bloc:BlocProvider.of(上下文),
    生成器:(BuildContext上下文,数据状态){
    如果(状态为初始状态){
    返回文本(“按下按钮”);
    
    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
      }
    )