首页 > 解决方案 > Flutter Bloc,Bloc 状态,导航?

问题描述

我现在面临的是在我按照其中一个教程实施 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(),
          ],
        ),
      ),
    ),
  );
}

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

标签: flutterbloc

解决方案


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

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

那么你可以使用类似的东西:

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

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

我认为使用命名路由最干净的方法。这是一个例子:

// 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);

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

了解更多导航:导航官方文档 还不错

关于 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

推荐阅读