http调用后无法更新列表(颤动)

时间:2018-03-31 12:21:50

标签: http dart future flutter

我是新手扑动

我尝试进行http调用,然后填充列表。问题是http调用工作正常,但UI不刷新。 我认为问题是框架在http调用完成之前用列表创建ui。比http呼叫结束时我无法更新ui。

我搜索但我没有找到任何东西。

编辑 - 在Listview.Builder中找到解决方案code here

http电话

 static Future<Map> getData() async {
    try{
    http.Response res = await http.get("http://...."); 
    Map data = JSON.decode(res.body);
    print(res.body);
    return data;
    }
    catch(exception){
      //todo
    }

  }

主要

  class _MyHomePageState extends State<MyHomePage> {
  List<Widget> _items = new List<GithubCardItem>();

  @override
  void initState() {
    super.initState();
    print("start download");
    _downloadData();
  }
  @override
  Widget build(BuildContext context) {

    return new Scaffold(
        appBar: new AppBar(title: new Text(widget.title)),
        body: new ListView.builder(
      itemBuilder: (BuildContext context, int index) => _items[index],
      itemExtent: 128.0,
      itemCount: _items.length,
    ),
        floatingActionButton: new FloatingActionButton(
          child: new Icon(Icons.add),
          onPressed: (){
            _downloadData();
          },
        )
    );
  }




 GithubCard _extractDataFromJson(Map githubCard){
     GithubCard card = new GithubCard(githubCard["name"], githubCard["avatar_url"], githubCard["description"], githubCard["stargazers_count"], githubCard["open_issued_count"]);
     return card;
}

  void _downloadData(){
    MyHttpCall.getData().then((jsonData) {
      //check if i have card to display
      if(jsonData["items"] != null){
        for(var githubCard in jsonData["items"]){
          setState(() {
            GithubCard card = _extractDataFromJson(githubCard);
            this._items.add(new GithubCardItem(card));
          });
          print("adding elements");
        }
      }
    });
  }
}

GithubCardItem是一个简单的无状态小部件,它返回一个文本。

2 个答案:

答案 0 :(得分:1)

试试这个:

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {----------- }

class MyHomePage extends StatefulWidget {-----------}

class _MyHomePageState extends State<MyHomePage> {
  List data;

  Future<String> getData() async {
    var response = await http.get(
        Uri.encodeFull("https://api.github.com/users"),
        headers: {"Accept": "application/json"});

    this.setState(() {
      data = json.decode(response.body);
    });
    return "Success!";
  }

  @override
  void initState() {
    this.getData();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Listviews"),
      ),
      body: new ListView.builder(
        itemCount: data == null ? 0 : data.length,
        itemBuilder: (BuildContext context, int position) {
          return new ListTile(
            title: new Text(data[position]['login'].toString()),
            subtitle: new Text(data[position]['url']),
            leading: new Image.network(data[position]['avatar_url']),
          );
        },
      ),
    );
  }
}

做得更简单,它正在工作。查看示例here

答案 1 :(得分:0)

使用ListView以及从网络获取数据有多种方法  这是您的问题的示例代码

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List list = new List();
  void fetchData() {
    getData().then((res) {
      setState(() {
        list.addAll(res);
      });
    });
  }

  @override
  void initState() {
    super.initState();
    fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new ListView.builder(
          itemCount: list.length,
          itemBuilder: ((BuildContext _context, int position) {
            return new ListTile(
              title: new Text( list[position]['login'].toString()),
              subtitle: new Text(list[position]['url']),
              leading: new Image.network(list[position]['avatar_url']),
            );   
          }),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: fetchData,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }

  Future<List> getData() async {
    var url = "https://api.github.com/users";
    List data = new List();
    var httpClient = new HttpClient();
    var request = await httpClient.getUrl(Uri.parse(url));
    var response = await request.close();
    if (response.statusCode == HttpStatus.OK) {
      var jsonString = await response.transform(utf8.decoder).join();
      data = json.decode(jsonString);
      return data;      
    }else{
      return data;
    }
  }
}