Flutter 颤振基于请求/响应隐藏元素-生成期间调用的错误setState()或markNeedsBuild()

Flutter 颤振基于请求/响应隐藏元素-生成期间调用的错误setState()或markNeedsBuild(),flutter,flutter-layout,Flutter,Flutter Layout,我是新的颤振,我需要隐藏一个元素后,从服务器得到响应,我使用的可见性属性,但我仍然得到问题,请纠正我,如果我在做错误的方式 最初,我用false声明一个变量_isGot,并基于此值设置元素的visible of属性,在得到响应后,我将_isGot设置为true,并使用setState()设置此值,但它抛出了错误 KlimaticState class KlimaticStateFul extends StatefulWidget { String _name; KlimaticStateF

我是新的颤振,我需要隐藏一个元素后,从服务器得到响应,我使用的可见性属性,但我仍然得到问题,请纠正我,如果我在做错误的方式

最初,我用false声明一个变量_isGot,并基于此值设置元素的visible of属性,在得到响应后,我将_isGot设置为true,并使用setState()设置此值,但它抛出了错误

KlimaticState

class KlimaticStateFul extends StatefulWidget {
 String _name;

 KlimaticStateFul(this._name);

  @override
 _KlimaticStateFulState createState() => _KlimaticStateFulState();
 }
    class _KlimaticStateFulState extends State<KlimaticStateFul> {
        bool _isGot = false;
         @override
        Widget build(BuildContext context) {
           return Scaffold(
             appBar: AppBar(
             backgroundColor: Colors.black87,
             centerTitle: true, 
            title: Text(
                 'Klimatic',
                   style: TextStyle(color: Colors.white),
             )),
           body: Stack(
              children: <Widget>[
              Container(
               decoration: BoxDecoration(
                image: DecorationImage(
                 image: AssetImage("icons/raining.jpeg"),
                 fit: BoxFit.cover,
               ),
               ),
            ), 
      Container(
        margin: EdgeInsets.fromLTRB(20, 350, 0, 0),
        child: _getWeatherData(context),
      ),
      Container(
        margin: EdgeInsets.fromLTRB(20, 300, 0, 0),
        child: Visibility(
            child: Text(
          _temp.toString() + 'F Temp',
          style: tempStyle(),
        ),
        visible: !_isGot),
          ),
        ],
      ),
    );
 }



        FutureBuilder<Response> _getWeatherData(BuildContext context) {
         print("Log:_getWeatherData with $_city");
         return FutureBuilder<Response>(
    future: Provider.of<PostApiService>(context)
        .getWeatherData(_city, '90dc4b035584894abff118a13d2a6d66'),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        final Map data = json.decode(snapshot.data.bodyString);
        return _buildPosts(context, data);
      } else {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
         });
      }

      Container _buildPosts(BuildContext context, Map data) {
//print('******Data************** $data');
if (data == null)
  return Container(
    child: Text('No data found'),
  );
else {
  double _temp = data['main']['temp'];
  print(data['main']);
    this._temp = _temp;
    _saveData(_temp.toString() + 'F');
    setState(() {
      _isGot = true;
    });
  return Container(
      child: Text(
    _temp.toString() + 'F',
    style: tempStyle(),
     ));
   }
  }
\u KlimaticStateFulState

class KlimaticStateFul extends StatefulWidget {
 String _name;

 KlimaticStateFul(this._name);

  @override
 _KlimaticStateFulState createState() => _KlimaticStateFulState();
 }
    class _KlimaticStateFulState extends State<KlimaticStateFul> {
        bool _isGot = false;
         @override
        Widget build(BuildContext context) {
           return Scaffold(
             appBar: AppBar(
             backgroundColor: Colors.black87,
             centerTitle: true, 
            title: Text(
                 'Klimatic',
                   style: TextStyle(color: Colors.white),
             )),
           body: Stack(
              children: <Widget>[
              Container(
               decoration: BoxDecoration(
                image: DecorationImage(
                 image: AssetImage("icons/raining.jpeg"),
                 fit: BoxFit.cover,
               ),
               ),
            ), 
      Container(
        margin: EdgeInsets.fromLTRB(20, 350, 0, 0),
        child: _getWeatherData(context),
      ),
      Container(
        margin: EdgeInsets.fromLTRB(20, 300, 0, 0),
        child: Visibility(
            child: Text(
          _temp.toString() + 'F Temp',
          style: tempStyle(),
        ),
        visible: !_isGot),
          ),
        ],
      ),
    );
 }



        FutureBuilder<Response> _getWeatherData(BuildContext context) {
         print("Log:_getWeatherData with $_city");
         return FutureBuilder<Response>(
    future: Provider.of<PostApiService>(context)
        .getWeatherData(_city, '90dc4b035584894abff118a13d2a6d66'),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        final Map data = json.decode(snapshot.data.bodyString);
        return _buildPosts(context, data);
      } else {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
         });
      }

      Container _buildPosts(BuildContext context, Map data) {
//print('******Data************** $data');
if (data == null)
  return Container(
    child: Text('No data found'),
  );
else {
  double _temp = data['main']['temp'];
  print(data['main']);
    this._temp = _temp;
    _saveData(_temp.toString() + 'F');
    setState(() {
      _isGot = true;
    });
  return Container(
      child: Text(
    _temp.toString() + 'F',
    style: tempStyle(),
     ));
   }
  }
class\u KlimaticStateFulState扩展状态{
bool _isGot=false;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
背景颜色:Colors.black87,
标题:对,
标题:正文(
“Klimatic”,
样式:TextStyle(颜色:Colors.white),
)),
主体:堆栈(
儿童:[
容器(
装饰:盒子装饰(
图像:装饰图像(
图像:AssetImage(“icons/raining.jpeg”),
适合:BoxFit.cover,
),
),
), 
容器(
边距:LTRB(20350,0,0)的边距,
子项:_getWeatherData(上下文),
),
容器(
边距:从LTRB(20,300,0,0)开始的边距集,
孩子:可见度(
子:文本(
_temp.toString()+'F temp',
样式:tempStyle(),
),
可见:!\u isGot),
),
],
),
);
}
FutureBuilder\u getWeatherData(构建上下文){
打印(“日志:_getweatherdatawith$_city”);
回归未来建设者(
未来:提供者(上下文)
.getWeatherData(_city,'90DC4B03584894ABFF118A13D2A6D66'),
生成器:(上下文,快照){
if(snapshot.connectionState==connectionState.done){
最终映射数据=json.decode(snapshot.data.bodyString);
返回构建帖子(上下文、数据);
}否则{
返回中心(
子对象:CircularProgressIndicator(),
);
}
});
}
容器_buildPosts(BuildContext上下文、映射数据){
//打印(“******数据***************$Data”);
如果(数据==null)
返回容器(
子项:文本(“未找到数据”),
);
否则{
双温=数据['main']['temp'];
打印(数据['main']);
这个。_temp=_temp;
_保存数据(_temp.toString()+'F');
设置状态(){
_isGot=true;
});
返回容器(
子:文本(
_临时toString()+'F',
样式:tempStyle(),
));
}
}

要使小部件隐藏显示,您必须有条件地返回小部件 示例:-

Container(
            margin: EdgeInsets.fromLTRB(20, 300, 0, 0),
            child: _isGot ? Text('F Temp',) : Container(),
          )

我们正在返回带有错误标志的空白容器。

问题

  • 调用
    build()
  • FutureBuilder
    触发
    getWeatherData()
  • 未来还没有结束,所以它显示了加载
  • 然后,未来将结束,现在由于连接状态已完成,
    \u buildPost()
    将被调用
  • 如果有数据,
    setState()
    将被调用,这将使
    build()
    
    build()
    将在返回最终小部件之前递归调用,这意味着 没有完成小部件子树的构建,这就是 框架不允许
  • 解决方案

    使用
    FutureBuilder
    包装取决于未来的小部件,在您的情况下,您可以使用
    FutureBuilder
    包装
    堆栈
    ,而不是将其放在一个
    容器
    中。这样,您可以从
    可见性
    小部件访问快照数据,并设置
    可见
    pr不动产

    建议

    • 这个
      json.decode(snapshot.data.bodyString)
      可以在 future调用并返回一个
      future
      ,然后您可以 使用快照数据访问该地图
    • 尝试使用方法
      snapshot.hasData
      snapshot.hasError

    在调用请求本身之前,我需要显示该元素,在得到响应之后,我需要隐藏该元素,以便在调用请求本身之前显示该元素,并为将起作用的_isget变量提供“true”默认值