FLUTTER:如何在流构建器中使用导航器?
Posted
技术标签:
【中文标题】FLUTTER:如何在流构建器中使用导航器?【英文标题】:FLUTTER: How to use navigator in streambuilder? 【发布时间】:2020-05-01 11:47:04 【问题描述】:我正在尝试在流构建器中导航,但出现以下错误:“setState() 或 markNeedsBuild() 在构建期间调用。”。如果我在按下的按钮内调用导航,它可以工作,但不能仅在条件内使用它。我被困住了。有一些代码给你看。
Widget build(BuildContext context)
return Scaffold(
body: StreamBuilder(
stream:
Firestore.instance.collection('rooms').document(pinid).snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot)
if (snapshot.hasData)
if ((snapshot.data['Votes'][0] + snapshot.data['Votes'][1]) >=
snapshot.data['joueurs'])
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Results(),
));
return Center(
child: Text('VOUS AVEZ VOTE'),
);
,
),
);
【问题讨论】:
【参考方案1】:这是因为当您尝试导航到另一个屏幕时,Flutter 会触发框架构建,因此这是不可能的。
您可以安排后帧回调,以便在 Flutter 完成该小部件的树重建后立即导航。
import 'package:flutter/foundation.dart';
WidgetsBinding.instance.addPostFrameCallback(
(_) => Navigator.push(context,
MaterialPageRoute(
builder: (context) => Results(),
),
),
);
【讨论】:
感谢您的回答!我把你的代码放在我的 if 条件下,但它重新加载了很多时间,就像它多次调用 Result 一样:/ 那是因为该流正在下沉很多事件。您必须确保每个事件只导航一次。 拯救了我的一天 【参考方案2】:如果导航是按钮按下时唯一发生的事情,我根本不会使用 Bloc,因为导航不是业务逻辑,应该由 UI 层完成。
如果您在按钮按下时具有业务逻辑并且需要根据一些动态信息进行导航,那么我将在表示层(小部件)中再次进行导航以响应如下所示的成功状态。您还可以根据需要更改导航逻辑。
Widget loginButton(LoginBloc loginBloc) =>
StreamBuilder<List<UserLoginResultElement>>(
stream: loginBloc.loginStream,
builder:
(context, AsyncSnapshot<List<UserLoginResultElement>> snapshot)
print(snapshot.connectionState);
Widget children;
if (snapshot.hasError)
children = Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: $snapshot.error'),
);
else
switch (snapshot.connectionState)
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.done:
case ConnectionState.active:
children = BlockButtonWidget(
text: Text(
"LOGIN",
style: TextStyle(color: Theme.of(context).primaryColor),
),
color: Theme.of(context).accentColor,
onPressed: () async
try
bloc.submit(_userNameController.value.text,
_passwordController.value.text, context);
catch (ex)
print(ex.toString());
,
);
break;
if (snapshot.data != null && snapshot.hasData)
if (snapshot.data[0].code == "1")
SchedulerBinding.instance.addPostFrameCallback((_)
Navigator.pushReplacementNamed(context, "/HomeScreen");
);
else
print(Login Failed');
return children;
);
【讨论】:
以上是关于FLUTTER:如何在流构建器中使用导航器?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”
在 Flutter 的流构建器中使用 Future 构建器是正确的