Flutter中的SetState

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

我已经通过从API获取数据并将其放入对象列表中来动态创建了列表视图,但是,当我打开屏幕时(通过按下另一个屏幕上的按钮来打开屏幕),这是获取ListView的唯一方法在屏幕上显示是进行热刷新。我试过在init_state函数中设置状态,但它似乎不起作用。

感谢您的帮助:)

class _PlanetListState extends State<PlanetList> {

List<Planet> planets = [];
String urlWeb = 'https://swapi.dev/api/planets/';

Future getData(String url) async {

    var response = await http.get(url);
    if (response.statusCode == 200) {
        var data = json.decode(response.body);

    Planet obj = Planet(
      name: data['name'],
      rotationPeriod: data['rotation_period'],
      orbitalPeriod: data['orbital_period'],
      diameter: data['diameter'],
      climate: data['climate'],
      gravity: data['gravity'],
      terrain: data['terrain'],
      population: data['population']
      );
      planets.add(obj);

      print(planets);
    }
}

@override
  void initState() {
    for (var i=0;i<62;i++){
      getData('$urlWeb$i/');
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Planets"),
        backgroundColor: Colors.amber[800],
      ),
      body: Container(
        color: Colors.black,
        child: ListView.builder(
          itemCount: planets.length,
          itemBuilder: (BuildContext context, int index){
            return Card(
              color: Colors.amber[600],
              margin:EdgeInsets.all(8),
              child: ListTile(
                leading: CircleAvatar(
                  backgroundColor: getColor(planets[index].climate),
                  backgroundImage: AssetImage('assets/planet.png'),
                ),
                contentPadding: EdgeInsets.all(5),
                title: Text('$index: ${planets[index].name}'),
                subtitle:Text(planets[index].climate),
             ),
           );
          },
        ),
      ),
    );
  }
}
flutter flutter-layout
1个回答
0
投票

发生的事情是,在将数据添加到列表之前,正在加载屏幕,这是因为getData函数是异步的。因此,当您的屏幕首次加载时,列表为空,并且您可能知道为了在屏幕上显示更改,您必须执行setState(),这就是为什么在热刷新时显示更改的原因。

现在您在这里有多个选项,首先您可以看一下FutureBuilder,这是一个将生成两次的窗口小部件,一次在Future解析之前,一次在此之后,意味着它“自动刷新”。在这种情况下,您的数据列表将成为Future类型,并且ListView将被FutureBuilder包装,以便在数据准备好之后将其构建。

© www.soinside.com 2019 - 2024. All rights reserved.