【问题标题】:Unable to refresh listview after fetching Json获取 Json 后无法刷新列表视图
【发布时间】:2018-10-23 05:56:46
【问题描述】:

我一直在尝试从服务器获取数据并将其显示在 futurebuilder 内的 listview.builder 中,但 listview 仅在应用 setstate() 后才更新,请帮助已经卡了一段时间。

  Future<dynamic> _fetchData() async {
    sPref.getUserId().then((onValue) {
      userIds = onValue;
    });
    sPref.getAuthToken().then((val) {
      token = val;
      var body = {
        'userId': '$userIds',
      };
      var client = http.Client();    

      var response = http.Request(
          'POST', Uri.parse('http://example.net/api/fetchJson'));    

      response.headers["Authorization"] = "Bearer $token";
      response.bodyFields = body;
      print(response.headers);
      client.send(response).then((response) {
        return http.Response.fromStream(response);
      }).then((res) {
        return res.body;
      }).then((body) {
        return json.decode(body);
      }).then((body) {
        print(body.toString());
        var datas = body['data'];
        if (body['status'] == 'success') {
          list = (datas as List)
              .map((data) => new PosModelData.fromJson(data))
              .toList();
          return list;
        } else {
          print('failed');
        }
      });
      return list;
    });
  }  

这就是我以后要称呼它的地方。需要知道我哪里出错了。

           body: FutureBuilder(
             future: _fetchData(),
             builder: (context, data) {
               switch (data.connectionState) {
                 case ConnectionState.none:
                 case ConnectionState.waiting:
                   return Center(child: CircularProgressIndicator());
                 default:
                   // if (data.hasError)
                   //   return new Text('Error: ${data.error}');
                   // else
                   return ListView.builder(
                     itemCount: list.length,
                     itemBuilder: (BuildContext context, int index) {
                       return Container(
                         padding: EdgeInsets.symmetric(
                             horizontal: 6.0, vertical: 4.0),
                         child: Card(
                           elevation: 10.0,
                           child: Column(children: <Widget>[
                             ListTile(
                               title: Text(list[index].firstName),
                               subtitle: list[index].phone != null
                                   ? Text(list[index].phone)
                                   : Text('Not mentioned'),
                               trailing: trailingText(index),
                             ),
                           ]),
                         ),

【问题讨论】:

    标签: android dart flutter flutter-layout dart-html


    【解决方案1】:

    在您的代码中,您没有从 _fetchData() 块中调用 return

    你的返回类型是Future,你需要使用await,在你的async块中指定你的返回类型List&lt;PosModelData&gt;return

    Future<List<PosModelData>> _fetchData() async {
      final response = await http.Request('POST', Uri.parse('http://example.net/api/fetchJson')); 
      final list = ... convert response to list
      return list;
    }
    

    然后你会从回调builder: (context, data) {}得到列表。

    请查看this 示例。

    更新 1

    不使用asyncawait,另一种使用Future 的方法是返回Future 类型。指定您的返回类型Future&lt;List&lt; PosModelData&gt;&gt; 并返回Future 类型

    return sPref.then((s) {}.

    请检查以下示例代码和Futures document 进行飞镖异步编程。

    Future<List<PosModelData>> _fetchData() {
      return Future.wait([sPref.getUserId(), sPref.getAuthToken()]).then((data) {
        userIds = data.first;
        token = data[1];
    
        var body = {
          'userId': '$userIds',
        };
        var client = http.Client();
    
        var response = http.Request(
            'POST', Uri.parse('http://example.net/api/fetchJson'));
    
        response.headers["Authorization"] = "Bearer $token";
        response.bodyFields = body;
        print(response.headers);
        return client.send(response).then((response) {
          return http.Response.fromStream(response);
        }).then((res) {
          return res.body;
        }).then((body) {
          return json.decode(body);
        }).then((body) {
          print(body.toString());
          var datas = body['data'];
          if (body['status'] == 'success') {
            list = (datas as List)
                .map((data) => new PosModelData.fromJson(data))
                .toList();
            return list;
          } else {
            print('failed');
          }
        });
      });
    

    【讨论】:

    • 我尝试在 sPref.getAuthtoken 中添加实现 await bt 不起作用。
    • 这可能有效,但 sPref 或 sharedPreference 的实例没有“.then”方法
    • 请检查更新的部分。您可以使用Future.wait 组合具有.then 方法的实例,例如sPref.getUserId()sPref.getAuthToken()
    • 太棒了,thanx 兄弟,它奏效了,我学到了一些新东西 :)
    猜你喜欢
    • 2022-07-07
    • 2018-09-23
    • 1970-01-01
    • 2012-04-25
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多