Flutter 对null调用了getter

Flutter 对null调用了getter,flutter,Flutter,我正在尝试显示ProgesBar,直到获取数据。在init状态下,我调用了api。它显示错误,如图所示,然后显示布局,但不显示进度条。我是一个新手,无法适应这一切 我已实施以下措施: @override void initState() { super.initState(); getDetails(); } @override Widget build(BuildContext context) { return Scaffold(

我正在尝试显示ProgesBar,直到获取数据。在init状态下,我调用了api。它显示错误,如图所示,然后显示布局,但不显示进度条。我是一个新手,无法适应这一切

我已实施以下措施:

     @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