我正在尝试从API提取数据,并且能够获取日志,但setState无法正常工作。总的来说,我想要实现的是是否有响应在屏幕上显示数据,API或服务器上是否有错误或我想在小吃栏中显示任何其他内容。我的moto也要显示错误。
下面是我的模特班
import 'http.dart';
class User {
int userId;
int id;
String title;
String body;
User({this.userId, this.id, this.title, this.body});
User.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
body = json['body'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userId'] = this.userId;
data['id'] = this.id;
data['title'] = this.title;
data['body'] = this.body;
return data;
}
}
class UserExt {
static getUserInfo(Function(User user) success, Function(String errorMesssage) error) async{
final response = await HTTP.get(api: "https://jsonplaceholder.typicode.com/posts/1");
if(response.isSuccess == true) {
success(User.fromJson(response.response));
} else {
error(response.response);
}
}
}
下面是我的http.dart文件
import 'dart:html';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' as convert;
import 'package:http/http.dart';
const _timeoutDuration = Duration(seconds: 5);
class HTTP {
static Future<HttpResponse> get({@required String api}) async {
try {
Response response = await http.get(api).timeout(_timeoutDuration);
return _modeledResponse(response);
} catch (error) {
return HttpResponse(isSuccess: false, response: error.toString());
}
}
static Future<HttpResponse> _modeledResponse(Response response) async {
try {
if(response.statusCode == HttpStatus.ok) {
var jsonResponse = convert.jsonDecode(response.body);
return HttpResponse(isSuccess: true, response: jsonResponse);
} else {
return HttpResponse(isSuccess: false, response: response.statusCode.toString());
}
} catch (error) {
return HttpResponse(isSuccess: false, response: error.toString());
}
}
}
class HttpResponse {
final bool isSuccess;
final dynamic response;
HttpResponse({@required this.isSuccess, @required this.response});
}
下面是我调用API的屏幕。
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http_request/User.dart';
import 'http.dart';
class ApiCalling extends StatefulWidget {
@override
_ApiCallingState createState() => _ApiCallingState();
}
class _ApiCallingState extends State<ApiCalling> {
bool showLoader = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Stack(
children: <Widget>[
Center(
child: RaisedButton(
child: Text("Call API"),
onPressed: () {
setState(() {
showLoader = true;
});
UserExt.getUserInfo((user){
print("UUUser id = ${user.userId}");
Scaffold.of(context).showSnackBar(SnackBar(content: Text("${user.userId}"),));
setState(() {
showLoader = false;
});
}, (error){
Scaffold.of(context).showSnackBar(SnackBar(content: Text("${error}"),));
setState(() {
showLoader = false;
});
});
},
),
),
Visibility(child: CircularProgressIndicator(backgroundColor: Colors.pink,), visible: showLoader,),
],
),
),
);
}
}
在当前代码中指示器未显示/隐藏或小吃栏也未显示。
从颤振https://api.flutter.dev/flutter/material/Scaffold/of.html的官方文档中>
,所以不要使用实例化脚手架的直接父级上下文,而应使用子级上下文。当在同一构建函数中实际创建了脚手架时,该构建函数的context参数不能用于找到该脚手架(因为它在窗口小部件树中返回的窗口小部件“上方”)。在这种情况下,可以使用以下带有Builder的技术来为BuildContext提供“在”脚手架下方的新作用域:
所以基本上问题出在您的脚手架上下文
下面的代码将起作用。
class _ApiCallingState extends State<ApiCalling> {
bool showLoader = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (context)=>
Center(
child: Stack(
children: <Widget>[
Center(
child: RaisedButton(
child: Text("Call API"),
onPressed: () {
setState(() {
showLoader = true;
});
UserExt.getUserInfo((user) {
print("UUUser id = ${user.userId}");
print("context==$context");
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(" User Id${user.userId}"),
));
setState(() {
showLoader = false;
});
}, (error) {
setState(() {
showLoader = false;
});
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("${error}"),
));
});
},
),
),
Visibility(
child:
Center(
child:CircularProgressIndicator(
backgroundColor: Colors.pink,
),
),
visible: showLoader,
)
],
),
),
)
);
}
}
只需进行以下更改和加载项,只需检查以下代码即可:
声明全局密钥final _scaffoldKey = GlobalKey();