我有一个屏幕,其中包含有关用户的一些信息。
在我的构建小部件中,我有这个:
Column
(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>
[
Text('User Points', style: TextStyle(color: Colors.blueAccent)),
Text('${this.user.points}', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w700, fontSize: 34.0))
],
),
我有一个功能,每次用户访问它时更新仪表板。
void updateDashboard() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
var api_key = prefs.getString('api_key');
var userID = prefs.getInt('userID');
var res = await http.post(('http://myApp.com/getDashboardPreferences/'+userID.toString() + '/' + api_key),
headers: {
"Accept": "application/json",
"content-type": "application/json"
});
this.user = User.fromJson(json.decode(res.body));
setState(() {
if (res.statusCode == 200) {
this.user.setPoints(this.user.points);
} else {
print("Something is wrong");
}
});
}
在initstate中我调用该函数:
@override
void initState() {
updateDashboard();
super.initState();
}
这有效,但是,我得到${this.user.points}
是null
几秒钟(我得到警告屏幕)然后它被加载,一切都很好。我想这是因为我的功能是async
...但是我怎么能保证在渲染updateDashboard()
之前调用这个Widget build()
?
如果你不想使用FutureBuilder
那么你可以做类似的事情
if(done)
Column( /* whatever */ )
else
Center(child: CircularProgressIndicator())
void updateDashboard() async{
/* whatever */
if (res.statusCode == 200) {
setState(() {
this.user.setPoints(this.user.points);
done = true;
});
}
@override
void initState() {
/* whatever */
done = false;
}
好吧,异步意味着数据可能需要一些时间来加载,并被转移到另一个线程加载。可以有多种非阻塞方式来执行此操作:
user
对象提供默认值,因此在async方法完成时,您将显示代理/默认值,setState()
确保在加载时显示新值。Text
时加载Container()
小部件。第二种方法的示例:
this.user!=null?Text('${this.user.points}'):Container()
这样,您不需要显示窗口小部件,直到值加载。这两种方法都可以使用,并且根据您的使用情况,您可以选择可以应用的方法。
您可以在返回小部件之前放置该函数。
你可以制作一个加载变量,如bool _loading
然后你开始loading
你async
函数,你可以setState
加载到真setState
loading
async
函数停止加载像这样。
void updateDashboard() async{
setState(() {
_loading = true;
});
SharedPreferences prefs = await SharedPreferences.getInstance();
var api_key = prefs.getString('api_key');
var userID = prefs.getInt('userID');
var res = await http.post(('http://myApp.com/getDashboardPreferences/'+userID.toString() + '/' + api_key),
headers: {
"Accept": "application/json",
"content-type": "application/json"
});
this.user = User.fromJson(json.decode(res.body));
setState(() {
if (res.statusCode == 200) {
this.user.setPoints(this.user.points);
} else {
print("Something is wrong");
}
_loading = false; //Set Loading to false
});
}
然后在您的小部件构建中,检查加载是否为真,并显示这样的进度指示器。
body: _loading
? Center(
child: CircularProgressIndicator( //Show a Circular Progress indicator
valueColor: new AlwaysStoppedAnimation<Color>(Colors.cyan),
),
)
:Column(//Show your Dashboard)
我希望它有所帮助