使用 FutureBuilder 触发 api 调用时未调用构建器
builder not been called when firing an api call using FutureBuilder
我试图在点击登录按钮时调用 api,api 已被调用,并返回正确的数据,但构建器未被调用,CircularProgressIndicator 也未被调用:
class _LoginState extends State<Login> {
Future<LoginModel> getLoginData(String username, String password) async {
var loginModel = await LoginAuthentication().login('name', 'pass');
return loginModel;
}
...
在按钮上单击我正在调用一个小部件
void _loginTapped(BuildContext context) {
buildLoginAPI(context);
}
Future<Widget> buildLoginAPI(BuildContext context) async {
return FutureBuilder<LoginModel>(
future: getLoginData('',''),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(
snapshot.error.toString(),
textAlign: TextAlign.center,
textScaleFactor: 1.3,
),
);
}
//TODO: Handle data: store the tokens in preferences
// final result = snapshot.data?.body;
} else {
return const CircularProgressIndicator();
}
return const CircularProgressIndicator();
},
);
}
我不明白你想在这里达到什么目的。
FutureBuilder 是一个小部件,我们用它来等待获取某些数据并根据该数据在屏幕上显示某些内容。
我假设您想显示正在获取的数据:
您不应该将 FutureBuilder 作为函数(在我们的例子中是 buildLoginAPI)中的 return 放置,而是应该将 FutureBuilder 直接放置在您的小部件树中(以您的脚手架主体为例)
这样,FutureBuilder 将显示从函数 getLoginData 获取的数据(请注意,您必须调用该函数才能获取数据,您可以通过在 initState 中调用它或按下按钮来实现)
示例:
//Here the FutureBuilder can be the body of a scaffold for example
return Scaffold(
body :FutureBuilder<LoginModel>(
future: getLoginData('',''),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(
snapshot.error.toString(),
textAlign: TextAlign.center,
textScaleFactor: 1.3,
),
);
}
//TODO: Handle data: store the tokens in preferences
// final result = snapshot.data?.body;
} else {
return const CircularProgressIndicator();
}
return const CircularProgressIndicator();
},
),
);
对于 getLoginData 函数,您可以通过按一个按钮来调用它,示例:
ElevatedButton(
child: Text("Fetch Data"),
onPressed: ()=>getLoginData('',''),
),
我试图在点击登录按钮时调用 api,api 已被调用,并返回正确的数据,但构建器未被调用,CircularProgressIndicator 也未被调用:
class _LoginState extends State<Login> {
Future<LoginModel> getLoginData(String username, String password) async {
var loginModel = await LoginAuthentication().login('name', 'pass');
return loginModel;
}
... 在按钮上单击我正在调用一个小部件
void _loginTapped(BuildContext context) {
buildLoginAPI(context);
}
Future<Widget> buildLoginAPI(BuildContext context) async {
return FutureBuilder<LoginModel>(
future: getLoginData('',''),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(
snapshot.error.toString(),
textAlign: TextAlign.center,
textScaleFactor: 1.3,
),
);
}
//TODO: Handle data: store the tokens in preferences
// final result = snapshot.data?.body;
} else {
return const CircularProgressIndicator();
}
return const CircularProgressIndicator();
},
);
}
我不明白你想在这里达到什么目的。 FutureBuilder 是一个小部件,我们用它来等待获取某些数据并根据该数据在屏幕上显示某些内容。 我假设您想显示正在获取的数据: 您不应该将 FutureBuilder 作为函数(在我们的例子中是 buildLoginAPI)中的 return 放置,而是应该将 FutureBuilder 直接放置在您的小部件树中(以您的脚手架主体为例) 这样,FutureBuilder 将显示从函数 getLoginData 获取的数据(请注意,您必须调用该函数才能获取数据,您可以通过在 initState 中调用它或按下按钮来实现)
示例:
//Here the FutureBuilder can be the body of a scaffold for example
return Scaffold(
body :FutureBuilder<LoginModel>(
future: getLoginData('',''),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(
snapshot.error.toString(),
textAlign: TextAlign.center,
textScaleFactor: 1.3,
),
);
}
//TODO: Handle data: store the tokens in preferences
// final result = snapshot.data?.body;
} else {
return const CircularProgressIndicator();
}
return const CircularProgressIndicator();
},
),
);
对于 getLoginData 函数,您可以通过按一个按钮来调用它,示例:
ElevatedButton(
child: Text("Fetch Data"),
onPressed: ()=>getLoginData('',''),
),