flutter - 构建 Builder(dirty, dependencies: [MediaQuery]): type 'Future' 不是 'Widget' 类型的子类型
问题描述
语境:
我正在使用 azure ad 构建一个简单的登录应用程序,该应用程序可以正常登录并获取令牌并很好地重定向到下一页,但在重定向之前它会引发错误
错误:
构建 Builder(dirty, dependencies: [MediaQuery]): type 'Future' is not a subtype of type 'Widget'
相关的导致错误的小部件是: Builder file:///D:/Projects/flutter/aims_mobile/lib/screens/authentication/signin.dart:101:17 当抛出异常时,这是堆栈:#0 _SignInState 。建造。(package:aims_mobile/screens/authentication/signin.dart:133:25) #1 Builder.build (package:flutter/src/widgets/basic.dart:7185:48) #2 StatelessElement.build (package:flutter/src /widgets/framework.dart:4749:28) #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:15) #4 Element.rebuild (package:flutter/src/widgets/framework.dart :4369:5)
代码
class _SignInState extends State<SignIn> {
static const String SCOPE ='';
static const String TENANT_ID = 'organizations';
static String authority = "";
MsalMobile msal;
bool isSignedIn = false;
@override
void initState() {
super.initState();
MsalMobile.create('assets/auth_config.json', authority).then((client) {
setState(() {
msal = client;
});
refreshSignedInStatus();
});
}
/// Updates the signed in state
refreshSignedInStatus() {
msal.getSignedIn().then((loggedIn) {
print('refreshing');
setState(() {
isSignedIn = loggedIn;
});
});
}
/// Signs a user in
handleSignIn() async {
await msal.signIn(null, [SCOPE]).then((result) {
refreshSignedInStatus();
}).catchError((exception) {
if (exception is MsalMobileException) {
logMsalMobileError(exception);
} else {
final ex = exception as Exception;
print('exception occurred');
print(ex.toString());
}
});
}
logMsalMobileError(MsalMobileException exception) {
print('${exception.errorCode}: ${exception.message}');
if (exception.innerException != null) {
print(
'inner exception = ${exception.innerException.errorCode}: ${exception.innerException.message}');
}
}
/// Signs a user out.
handleSignOut() async {
try {
print('signing out');
await msal.signOut();
print('signout done');
refreshSignedInStatus();
} on MsalMobileException catch (exception) {
logMsalMobileError(exception);
}
}
/// Gets the current and prior accounts.
handleGetAccount() async {
await msal.getAccount().then((result) {
if (result.currentAccount != null) {
print('current account id: ${result.currentAccount.id}');
print('current account id: ${result.currentAccount.username}');
} else {
print('no account found');
}
}).catchError((exception) {
if (exception is MsalMobileException) {
logMsalMobileError(exception);
} else {
print('exception occurred');
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: new Scaffold(
body: Builder(
builder: (context) => Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Image.asset('assets/landing.webp',
fit: BoxFit.fill,
color: Color.fromRGBO(255, 255, 255, 0.6),
colorBlendMode: BlendMode.modulate),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 10.0),
Container(
width: 130.0,
child: Align(
alignment: Alignment.center,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
color: Color(0xffffffff),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
isSignedIn
? Future.delayed(Duration.zero, () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => NavScreen()));
})
: RaisedButton(
child: Text("Sign In"),
onPressed: handleSignIn,
),
],
),
)),
)
],
),
],
),
),
));
}
}
我不知道如何解决这个问题
解决方案
您正在传递一个函数Future
,而不是Widget
导致此错误的函数。
isSignedIn
? Future.delayed(Duration.zero, () { // <---- This is not a widget
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => NavScreen()));
})
: RaisedButton(
child: Text("Sign In"),
onPressed: handleSignIn,
),
而不是这样做,您可以使用Visibility
小部件隐藏/显示您的“登录”按钮并使用bool isSignedIn
,您可以处理导航代码。
Visibility(
visible: !isSignedIn,
child: RaisedButton(
child: Text("Sign In"),
onPressed: handleSignIn,
),
),
initState
你应该在你的方法中处理导航StatefulWidget
,看起来像这样:
@override
void initState() {
super.initState();
signInNavigation();
}
Future<void> signInNavigation() async {
// isSignedIn = await yourMethodWhichReturnsSignInStatus(); <-- Replace this with your method
if(isSignedIn) {
// Your navigation code
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => NavScreen()));
}
}
推荐阅读
- c++ - 是否可以在单个通用参考方法中实现 std::vector 的两个 push_back(..) 方法?
- facebook-graph-api - 从 messenger api 获取 public_profile
- php - 无法发送邮件,找不到错误
- javascript - 如何在不重复的情况下使用 asyncstorage?
- mysql - Django MySQL - 正确的连接方式
- yaml - 尝试使用 GitHub 操作部署到 Azure
- azure - 在 Azure 门户中哪里可以找到自定义指标
- java - BCryptPasswordEncoder 适用于超过 72 个字节,如何?
- c - 在C中搜索二叉树中的节点
- directus - docker中的Directus无法连接到docker中的mysql数据库