Flutter 对null调用了getter
我正在尝试显示ProgesBar,直到获取数据。在init状态下,我调用了api。它显示错误,如图所示,然后显示布局,但不显示进度条。我是一个新手,无法适应这一切 我已实施以下措施:Flutter 对null调用了getter,flutter,Flutter,我正在尝试显示ProgesBar,直到获取数据。在init状态下,我调用了api。它显示错误,如图所示,然后显示布局,但不显示进度条。我是一个新手,无法适应这一切 我已实施以下措施: @override void initState() { super.initState(); getDetails(); } @override Widget build(BuildContext context) { return Scaffold(
@override
void initState() {
super.initState();
getDetails();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
title: Text(
"Menu Details",
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
body: _isLoading
? Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
)
: _buildLayout()
);
}
GetDetails方法
void getDetails() async {
setState(() {
_isLoading = true;
});
MenuDetailsResponse moreResponse = await getMenuDetails(widget.id);
if (moreResponse != null && moreResponse.data != null) {
setState(() {
details = moreResponse.data;
if (details.detail.maxQty != null) {
maxQtyController =
new TextEditingController(text: details.detail.maxQty.toString());
} else {
maxQtyController = new TextEditingController();
}
print(details);
_isLoading = false;
});
} else if (moreResponse != null) {
setState(() {
_isLoading = false;
});
showAlerts(context, "Sorry!!", moreResponse.message, AlertType.error);
} else {
setState(() {
_isLoading = false;
});
showAlerts(context, "Sorry!!",
"Something went wrong, Please try again later!!", AlertType.error);
}
}
构建方法:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
title: Text(
"Menu Details",
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
body: Stack(
children: <Widget>[
Opacity(
opacity: _isLoading
? 0.3
: 1, // You can reduce this when loading to give different effect
child: AbsorbPointer(
absorbing: _isLoading,
child: _buildLayout(),
),
),
Opacity(
opacity: _isLoading ? 1.0 : 0,
child: Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
)),
],
),
);
}
@覆盖
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
背景颜色:Colors.white,
iconTheme:IconThemeData(颜色:Theme.of(context.primaryColor)),
标题:正文(
“菜单详情”,
样式:TextStyle(颜色:Theme.of(context).primaryColor),
),
),
主体:堆栈(
儿童:[
不透明(
不透明度:_正在加载
? 0.3
:1,//您可以在加载时减少此值以提供不同的效果
儿童:吸收点(
吸收:_isLoading,
子项:_buildLayout(),
),
),
不透明(
不透明度:_isLoading?1.0:0,
儿童:中心(
子对象:循环压缩机指示器(
背景色:主题。背景色,
),
)),
],
),
);
}
BuildLayout小部件
Widget _buildLayout() {
return Container(
margin: EdgeInsets.all(10),
child: Wrap(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(height: 20),
Text(
"Enter max quantity for today",
style: TextStyle(color: Theme.of(context).primaryColor),
),
SizedBox(height: 20),
_buildTopItems(),
],
)
],
),
);
}
Widget\u buildLayout(){
返回容器(
保证金:所有(10),
孩子:包裹(
儿童:[
纵队(
儿童:[
尺寸箱(高度:20),
正文(
“输入今天的最大数量”,
样式:TextStyle(颜色:Theme.of(context).primaryColor),
),
尺寸箱(高度:20),
_buildTopItems(),
],
)
],
),
);
}
小部件topItems
Widget _buildTopItems() {
return Container(
margin: EdgeInsets.only(top: 10),
child: Wrap(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
child: Image.network(
details.detail.image,
height: 150,
width: 150,
fit: BoxFit.fill,
),
),
SizedBox(
width: 10,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
details.detail.name,
style: TextStyle(fontSize: 18),
),
SizedBox(height: 5),
Row(
children: <Widget>[
Text("Rs " + details.detail.price.toString(),
style: TextStyle(
decoration: TextDecoration.lineThrough)),
SizedBox(width: 5),
Text("Rs " + details.detail.discountPrice.toString(),
style: TextStyle(
fontSize: 17,
color: Theme.of(context).primaryColor,
))
],
),
SizedBox(height: 5),
Text(details.detail.foodtypedata.foodType),
SizedBox(height: 5),
StarRating(
rating: double.parse(details.detail.rating),
size: 24.0,
),
SizedBox(height: 5),
details.detail.status >= 1
? Text(
"Available",
style: TextStyle(
color: Theme.of(context).primaryColor),
)
: Text(
"UnAvailable",
style: TextStyle(color: Colors.red),
),
Text(
"- " + details.detail.createdAt,
textAlign: TextAlign.left,
),
],
))
]),
],
),
);
}
Widget\u buildTopItems(){
返回容器(
页边空白:仅限边集(前10页),
孩子:包裹(
儿童:[
划船(
mainAxisAlignment:mainAxisAlignment.start,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
容器(
孩子:Image.network(
细节,细节,图像,
身高:150,
宽度:150,
fit:BoxFit.fill,
),
),
大小盒子(
宽度:10,
),
扩大(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
正文(
details.detail.name,
样式:TextStyle(字体大小:18),
),
尺寸箱(高度:5),
划船(
儿童:[
Text(“Rs”+details.detail.price.toString(),
样式:TextStyle(
装饰:textEdition.lineThrough),
尺寸箱(宽度:5),
Text(“Rs”+details.detail.discountPrice.toString(),
样式:TextStyle(
尺寸:17,
颜色:主题。背景。原色,
))
],
),
尺寸箱(高度:5),
文本(details.detail.foodtypedata.foodType),
尺寸箱(高度:5),
主演(
评级:double.parse(details.detail.rating),
尺寸:24.0,
),
尺寸箱(高度:5),
details.detail.status>=1
?文本(
“可用”,
样式:TextStyle(
颜色:主题(上下文)。原色),
)
:文本(
“不可用”,
样式:TextStyle(颜色:Colors.red),
),
正文(
“-”+details.detail.createdAt,
textAlign:textAlign.left,
),
],
))
]),
],
),
);
}
在我看来,details
是一个类字段,当第一次调用build
时,它将是null
这是因为您正在initState
上填写details
,但是getDetails
是一个异步调用,因此initState
将执行并排队getDetails
,因为它是未来的
,所以它在未来执行,而不是现在。现在flatter进入build
,在那里访问details
,它仍然是null
如果您需要
构建方法中的未来
数据,请使用FutureBuilder
我通过更改构建方法解决了此问题,如下所示:
@override
void initState() {
super.initState();
getDetails();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
title: Text(
"Menu Details",
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
body: _isLoading
? Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
)
: _buildLayout()
);
}
这是代码中唯一一个名为详细信息
的字段吗?@mFeinstein否在详细信息
的每个位置都有一个断点。错误消息说它是在一个null
实例上被调用的(我看不出你总是检查它的null
),你的代码看起来不好看setState()
不应该包含所有这些代码,setState()
应该非常简短,例如setState((){isLoading=true;})代码>,它应该只设置一个标志和nothi