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

问题描述 投票:0回答:2

我是新手,在收到服务器响应后我需要隐藏一个元素,我正在使用可视性属性,但仍然出现问题,如果我做错了方法,请纠正我。

最初,我用false声明一个变量_isGot并基于此值,我设置element的property的visible,获得响应后,我将_isGot设置为true并使用setState()设置此值,但抛出错误。

KlimaticState

class KlimaticStateFul extends StatefulWidget {
 String _name;

 KlimaticStateFul(this._name);

  @override
 _KlimaticStateFulState createState() => _KlimaticStateFulState();
 }

_ 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(),
     ));
   }
  }
flutter flutter-layout
2个回答
0
投票

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

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

我们将在错误标志上返回空白容器。


0
投票

问题

  1. build()被呼叫
  2. [FutureBuilder触发getWeatherData()
  3. 未来还没有结束,所以它显示了负载
  4. 然后,将来完成,因为连接状态完成,所以调用了_buildPost()
  5. [如果有数据,就会调用setState(),这会使build()被再次调用,但是您会收到一个错误消息,因为build()将在返回最终小部件之前递归调用,这意味着无需完成构建小部件的子树,那就是框架不允许。

解决方案

FutureBuilder包裹取决于未来的小部件,在您的情况下,您可以用Stack包裹FutureBuilder,而不是将其放在Containers之一内。这样,您可以从Visibility小部件访问快照数据,并据此设置visible属性。

建议

  • json.decode(snapshot.data.bodyString)可以在将来致电并返回Future<Map<String, dynamic>>,则可以使用snapshot.data访问该地图
  • 尝试使用方法snapshot.hasDatasnapshot.hasError
© www.soinside.com 2019 - 2024. All rights reserved.