我有一个屏幕,其中包含有关用户的一些信息。
在我的构建小部件中,我有这个:
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");
}
});
}
在初始化状态下,我调用该函数:
@override
void initState() {
updateDashboard();
super.initState();
}
这有效,但是,我发现${this.user.points}
是null
了几秒钟(我得到了警告屏幕),然后加载了它,一切正常。我猜是因为我的函数是async
...但是我如何确保在渲染updateDashboard()
之前调用此Widget build()
?
答案 0 :(得分:1)
好吧,异步意味着数据可能需要花费一些时间才能加载,并且会移交给另一个线程进行加载。可以有多种非阻塞方式来做到这一点:
为user
对象提供默认值,因此在异步方法完成时,您将显示代理/默认值,并且setState()
确保在加载时显示新值。
此方法要求您有条件地加载小部件,即在有数据时加载Text
小部件,否则加载Container()
。
第二种方法的示例:
this.user!=null?Text('${this.user.points}'):Container()
这样,您无需在加载值之前显示小部件。两种方法都有效,并且取决于您的用例,您可以选择可以应用的方法。
答案 1 :(得分:1)
如果您不想使用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;
}
答案 2 :(得分:0)
您可以将函数放在返回小部件之前。
答案 3 :(得分:0)
您可以创建一个bool _loading
之类的加载变量,然后在任何开始loading
的地方async
函数中,可以setState
加载为true,然后setState
当loading
函数停止像这样加载时,{1}}为false。
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
});
}
我希望对您有帮助