【问题标题】:Flutter Bloc , Bloc state , navigate?Flutter Bloc,Bloc 状态,导航?
【发布时间】:2020-05-06 13:09:57
【问题描述】:

我现在面临的是在我按照其中一个教程实施 bloc 之后,我现在被困在一个地方,在我得到响应并且状态改变之后,我想导航到另一个小部件

@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(APP_TITLE),
        ),
        body: buildBody(context));
  }
}

BlocProvider<SignInBloc> buildBody(BuildContext context) {

  return BlocProvider(
    create: (_) => sl<SignInBloc>(),
    child: Center(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: <Widget>[
            BlocBuilder<SignInBloc, SignInState>(
                builder: (context, state) {
                  if(state is Empty)
                    return MessageDisplay(message: 'Sign In please.',);
                  else if(state is Loaded)
                    return HomePage();
                  else
                    return MessageDisplay(message: 'Sign In please.',);
                }
            ),
            SignInControls(),
          ],
        ),
      ),
    ),
  );
}

在加载状态下,我想导航到另一个小部件。 那么如何实现这一目标,最好的方法是什么?

【问题讨论】:

  • 有什么问题?你试过什么?
  • 在状态变为 Loaded 后,我正在尝试访问 HomePage(),但它不起作用因为它已添加到当前在屏幕上令人兴奋的小部件中,并且屏幕上会出现像素超载。我想导航到主页作为新屏幕。我希望这能让我的问题更清楚

标签: flutter bloc


【解决方案1】:

导航可以像继承的小部件一样使用:

Navigator nav = Navigator.of(this.context);

然后你可以使用类似的东西:

nav.push(MaterialPageRoute(builder: (context) => YourSecondPage()))

在颤振中,你不能直接移动到某个页面。你应该使用路线。

我认为使用named routes 的最简洁方式。这是一个例子:

// here you put a class of names to use later in all of your project.
class RouteNames{
    static String homepage = "/";
    static String otherPage= "/otherpage";
}
// in your main file , MyApp class
var routes = {
    RouteNames.homepage: (context)=> new MyHomePage(),
    RouteNames.otherPage: (context)=> new MyOtherPage()
};
// then use routes variable in your MaterialApp constructor 


// and later on in your project you can use this syntax: 
Navigator.of(context).pushNamed(RouteNames.otherPage);

我认为这种方式很干净而且是集中的,如果你想向路由发送参数是很好的。

要了解更多关于导航的信息:navigation official documentation 很不错

关于 Bloc 构建器和监听器的说明:

因为 BlocBuilder 会被调用很多次。它应该只包含小部件和小部件。如果你把导航代码放在里面,这个代码会被调用多次。

正如 Ayham Orfali 所说,您绝对应该为此使用 BlocListener。在它里面你可以听到状态的变化。这是一个例子

// some code
children: <Widget>[
            BlocListener(
                 bloc: BlocProvider.of<SignInBloc>(context),
                 listener: (context, state) {
                     if(state is Loaded){
                          Navigator.of(context).pushNamed("some other page");
                     }
                       // else do nothing!
                 }, 
                 child:// just bloc builder which contains widgets only.  ,
            SignInControls(),
          ]

// some other code

【讨论】:

    【解决方案2】:

    在构建小部件时,您不能使用导航器或更改状态(您的情况)。 有两种方法

    1.老套路

    WidgetsBinding.instance.addPostFrameCallback((_){
      // Your code goes here
    });
    

    2。由于您已经实现了 BLOC 库,因此您可以使用BlocListener 以更优雅的方式实现此目的。你可以在documentation了解更多信息

    希望我能帮上忙!

    【讨论】:

    • BlocListener 要好得多。有时颤动不会重绘 UI,在这种情况下,导航不会被触发,直到你对应用程序“做”一些事情,比如触摸屏幕或其他东西。当您在等待某个进度条并且屏幕在您触摸它之前不会移动时,这是非常麻烦的。
    • 感谢@Ayham Orfali,这真的很有帮助。
    猜你喜欢
    • 2021-03-19
    • 2020-03-26
    • 2020-07-09
    • 2021-03-04
    • 2020-04-12
    • 2021-07-27
    • 2020-10-10
    • 2020-06-17
    • 2019-07-05
    相关资源
    最近更新 更多