Flutter StreamBuilder子更新在导航后不渲染
我使用Flatter的Flutter StreamBuilder子更新在导航后不渲染,flutter,stream-builder,Flutter,Stream Builder,我使用Flatter的StreamBuilder来决定向用户显示哪个“根”页面。现在基本上有两种可能性-登录页面或主页。我的应用程序的主要构建方法如下所示: Widget build(BuildContext context) => StreamProvider.value( initialData: CurrentUser.initial, value: AuthService().user, child: Consumer<CurrentU
StreamBuilder
来决定向用户显示哪个“根”页面。现在基本上有两种可能性-登录页面
或主页
。我的应用程序的主要构建方法如下所示:
Widget build(BuildContext context) => StreamProvider.value(
initialData: CurrentUser.initial,
value: AuthService().user,
child: Consumer<CurrentUser>(
builder: (context, currentUser, _) => MaterialApp(
home: currentUser.isInitialValue
? Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
)
: currentUser.user != null
? MultiProvider(providers: [
Provider<User>.value(value: currentUser.user),
// NOTE: Any other user-bound providers here can be added here
], child: HomePage())
: LoginPage())));
App
|
|-- StreamBuilder
|-- Navigator()
|-- LoginPage()
|-- LoginPage(mode: LoginPageMode.signUp)
成功登录或注册后,将更新流,并呈现主页
。我知道这一点,因为我在build方法中有一个print语句(“Building HomePage”
):
然而,屏幕实际上并没有改变。屏幕仍保留在登录页面上。我认为我可以很好地管理流,因为如果我不是,渲染方法将永远不会被击中。我看到了一个类似的问题,但他们似乎没有正确管理流。如何才能看到渲染方法命中,而屏幕保持不变?我和弗利特一起工作有一段时间了,我以前从未见过这种情况
我认为这与导航有关,因为如果我删除用户选择“登录”或“注册”的步骤,并将其发送到登录页面,问题就会消失。这就像是在导航到的页面下构建主页。1。解释
这种行为的原因是您使用根导航器在应用程序根级别推送LoginPage
route。下面是widgets树,显示推送后的widgets关系:
App
|
|-- StreamBuilder
| |--LoginPage()
|
|-- LoginPage(mode: LoginPageMode.signUp)
因此,当StreamBuilder更改数据时,树将变成:
App
|
|-- StreamBuilder
| |--HomePage() // <--- CHANGED
|
|-- LoginPage(mode: LoginPageMode.signUp)
在这种情况下,当您调用Navigator.push(context,…)
内部LoginPage
时,您的小部件树将如下所示:
Widget build(BuildContext context) => StreamProvider.value(
initialData: CurrentUser.initial,
value: AuthService().user,
child: Consumer<CurrentUser>(
builder: (context, currentUser, _) => MaterialApp(
home: currentUser.isInitialValue
? Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
)
: currentUser.user != null
? MultiProvider(providers: [
Provider<User>.value(value: currentUser.user),
// NOTE: Any other user-bound providers here can be added here
], child: HomePage())
: LoginPage())));
App
|
|-- StreamBuilder
|-- Navigator()
|-- LoginPage()
|-- LoginPage(mode: LoginPageMode.signUp)
请尝试这种方法,它应该会起作用。1。解释
这种行为的原因是您使用根导航器在应用程序根级别推送LoginPage
route。下面是widgets树,显示推送后的widgets关系:
App
|
|-- StreamBuilder
| |--LoginPage()
|
|-- LoginPage(mode: LoginPageMode.signUp)
因此,当StreamBuilder更改数据时,树将变成:
App
|
|-- StreamBuilder
| |--HomePage() // <--- CHANGED
|
|-- LoginPage(mode: LoginPageMode.signUp)
在这种情况下,当您调用Navigator.push(context,…)
内部LoginPage
时,您的小部件树将如下所示:
Widget build(BuildContext context) => StreamProvider.value(
initialData: CurrentUser.initial,
value: AuthService().user,
child: Consumer<CurrentUser>(
builder: (context, currentUser, _) => MaterialApp(
home: currentUser.isInitialValue
? Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
)
: currentUser.user != null
? MultiProvider(providers: [
Provider<User>.value(value: currentUser.user),
// NOTE: Any other user-bound providers here can be added here
], child: HomePage())
: LoginPage())));
App
|
|-- StreamBuilder
|-- Navigator()
|-- LoginPage()
|-- LoginPage(mode: LoginPageMode.signUp)
请尝试这种方法,它应该会起作用。将key:UniqueKey(),
添加到MaterialApp
中确实有帮助,我一直在摆弄MaterialApp键。但是,它确实会导致一种奇怪的临时状态,在进入主页之前,它会返回登录页面
几秒钟。但是,如果我手动构建键key=user==null?“user null':'${user.id}'
,它可以工作,而这种奇怪的中间状态不会发生。一个感觉不对,另一个感觉不舒服。为什么在执行build方法时不进行flatter渲染?我以为键是用来确定是否调用build,而不是用来确定是否绘制屏幕……我不知道这是MaterialApp
widget的一个bug还是一个功能-我需要检查官方文档和源代码addkey:UniqueKey(),
toMaterialApp
这确实有帮助,我一直在摆弄MaterialApp键。但是,它确实会导致一种奇怪的临时状态,在进入主页之前,它会返回登录页面
几秒钟。但是,如果我手动构建键key=user==null?“user null':'${user.id}'
,它可以工作,而这种奇怪的中间状态不会发生。一个感觉不对,另一个感觉不舒服。为什么在执行build方法时不进行flatter渲染?我以为键是用来决定是否调用build,而不是用来决定是否绘制屏幕…我不知道这是否是MaterialApp
widget的bug或功能-我需要检查官方文档和源代码