为什么 futureBuilder 回调在 facebook 以 flutter 登录数据后不调用?
why futureBuilder callback is not calling after facebook logged in data in flutter?
我是 flutter 的新手,所以如果我是 wrong.In 我的应用程序,请告诉我我必须使用 facebook 登录,所以我使用了 RawMaterialButton
和 onPressed
函数使用以下代码
child: RawMaterialButton(
onPressed: () {
FutureBuilder<String>(
future:
_login(), // function where you call your api
builder: (BuildContext context,
AsyncSnapshot<String> snapshot) {
// AsyncSnapshot<Your object type>
print(snapshot);
if (snapshot.connectionState ==
ConnectionState.done) {
print('${snapshot.data}');
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: Text('Please wait its loading...'));
} else {
if (snapshot.hasError)
return Center(
child: Text('Error: ${snapshot.error}'));
else
return Center(
child: new Text(
'${snapshot.data}')); // snapshot.data :- get your object which is pass from your downloadData() function
}
},
);
return CircularProgressIndicator();
},
当我按下按钮调用方法时,我正在获取数据,但在获取这些数据之后,未来的构建不会更新或在 Text
中显示该数据。这是我的数据获取方法。
Future<String> _login() async {
final result = await FacebookAuth.instance.login();
var tokenString;
switch (result.status) {
case FacebookAuthLoginResponse.ok:
_printCredentials(result);
// get the user data
// final userData = await FacebookAuth.instance.getUserData();
tokenString = result.accessToken.token;
break;
case FacebookAuthLoginResponse.cancelled:
print("login cancelled");
tokenString = "User cancelled";
break;
default:
tokenString = "Login failed";
}
return tokenString;
}
出于调试目的,我也做了断点,但它不指向 asynchronous snapshot
条件状态 checking.I 找不到原因。我也检查以下堆栈问题。
好吧,在您的 onPressed 函数中,您声明了一个 FutureBuilder,这绝对是错误的。 FutureBuilder 允许您对函数或方法发出异步请求,以根据快照值使用响应数据构建小部件或其他小部件。当您第一次 运行 小部件或在 StatefulWidget 中使用 SetState({}) 时会发生这种情况。但是您正在将视图代码与功能代码结合起来。这是实现 FutureBuilder 的方法:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _login(),
builder: (context, snapshot) {
print(snapshot);
if (snapshot.connectionState == ConnectionState.done) {
print('${snapshot.data}');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
// Or return CircularProgressIndicator();
} else {
if (snapshot.hasError)
return Center(child: Text('Error: ${snapshot.error}'));
else
return Center(
child: new Text(
'${snapshot.data}'));
}
},
);
// if you return something here, it's dead code
}
但我建议您以这种方式实现 FutureBuilder:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: FutureBuilder(
future: _login(),
builder: (context, snapshot) {
if (snapshot.hasError) // if it has error
return Text('Error: ${snapshot.error}');
if (!snapshot.hasData) {
// if it's loading
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Please wait its loading...'),
Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
height: 35,
width: 35,
child: CircularProgressIndicator(),
),
),
],
);
} else {
// if everything success
print(snapshot.data);
return Text('${snapshot.data}');
}
},
),
);
}
最后,我想你想要的是使用 Provider 在登录页面的小部件之间创建一种通信方式,因为你想通过按下按钮来更改 page/view 小部件的状态,你可以使用一个 StatefulWidget 但你应该看到 this tutorial better. and here 是提供者文档。
Pdst:但是,如果您不想实现提供程序,您可以在按钮中发出 _login() 请求,例如:
onPressed: () async {
String response = await _login();
Navigator.push(context, MaterialPageRoute(builder: (context) => ResponseWidget(response)));
}
使用 navigator.push()
,您可以更改屏幕上的 view/page/widget 并显示一个新的小部件,该小部件可以显示与响应值相关的内容。
我是 flutter 的新手,所以如果我是 wrong.In 我的应用程序,请告诉我我必须使用 facebook 登录,所以我使用了 RawMaterialButton
和 onPressed
函数使用以下代码
child: RawMaterialButton(
onPressed: () {
FutureBuilder<String>(
future:
_login(), // function where you call your api
builder: (BuildContext context,
AsyncSnapshot<String> snapshot) {
// AsyncSnapshot<Your object type>
print(snapshot);
if (snapshot.connectionState ==
ConnectionState.done) {
print('${snapshot.data}');
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: Text('Please wait its loading...'));
} else {
if (snapshot.hasError)
return Center(
child: Text('Error: ${snapshot.error}'));
else
return Center(
child: new Text(
'${snapshot.data}')); // snapshot.data :- get your object which is pass from your downloadData() function
}
},
);
return CircularProgressIndicator();
},
当我按下按钮调用方法时,我正在获取数据,但在获取这些数据之后,未来的构建不会更新或在 Text
中显示该数据。这是我的数据获取方法。
Future<String> _login() async {
final result = await FacebookAuth.instance.login();
var tokenString;
switch (result.status) {
case FacebookAuthLoginResponse.ok:
_printCredentials(result);
// get the user data
// final userData = await FacebookAuth.instance.getUserData();
tokenString = result.accessToken.token;
break;
case FacebookAuthLoginResponse.cancelled:
print("login cancelled");
tokenString = "User cancelled";
break;
default:
tokenString = "Login failed";
}
return tokenString;
}
出于调试目的,我也做了断点,但它不指向 asynchronous snapshot
条件状态 checking.I 找不到原因。我也检查以下堆栈问题。
好吧,在您的 onPressed 函数中,您声明了一个 FutureBuilder,这绝对是错误的。 FutureBuilder 允许您对函数或方法发出异步请求,以根据快照值使用响应数据构建小部件或其他小部件。当您第一次 运行 小部件或在 StatefulWidget 中使用 SetState({}) 时会发生这种情况。但是您正在将视图代码与功能代码结合起来。这是实现 FutureBuilder 的方法:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _login(),
builder: (context, snapshot) {
print(snapshot);
if (snapshot.connectionState == ConnectionState.done) {
print('${snapshot.data}');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
// Or return CircularProgressIndicator();
} else {
if (snapshot.hasError)
return Center(child: Text('Error: ${snapshot.error}'));
else
return Center(
child: new Text(
'${snapshot.data}'));
}
},
);
// if you return something here, it's dead code
}
但我建议您以这种方式实现 FutureBuilder:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: FutureBuilder(
future: _login(),
builder: (context, snapshot) {
if (snapshot.hasError) // if it has error
return Text('Error: ${snapshot.error}');
if (!snapshot.hasData) {
// if it's loading
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Please wait its loading...'),
Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
height: 35,
width: 35,
child: CircularProgressIndicator(),
),
),
],
);
} else {
// if everything success
print(snapshot.data);
return Text('${snapshot.data}');
}
},
),
);
}
最后,我想你想要的是使用 Provider 在登录页面的小部件之间创建一种通信方式,因为你想通过按下按钮来更改 page/view 小部件的状态,你可以使用一个 StatefulWidget 但你应该看到 this tutorial better. and here 是提供者文档。
Pdst:但是,如果您不想实现提供程序,您可以在按钮中发出 _login() 请求,例如:
onPressed: () async {
String response = await _login();
Navigator.push(context, MaterialPageRoute(builder: (context) => ResponseWidget(response)));
}
使用 navigator.push()
,您可以更改屏幕上的 view/page/widget 并显示一个新的小部件,该小部件可以显示与响应值相关的内容。