SetState во Flutter - PullRequest
       1

SetState во Flutter

1 голос
/ 26 мая 2020

Я динамически создал представление списка, получив данные из API и поместив его в список объектов, однако, когда я открываю экран, который открывается нажатием кнопки на другом экране, единственный способ получить ListView для отображения на экране - это горячая перезагрузка sh. Я пробовал установить состояние в функции 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),
             ),
           );
          },
        ),
      ),
    );
  }
}

1 Ответ

0 голосов
/ 26 мая 2020

Что происходит, так это то, что ваш экран загружается до того, как ваши данные будут добавлены в список, это потому, что ваша функция getData является asyn c. Поэтому, когда ваш экран впервые загружается, список пуст, и, как вы, возможно, знаете, чтобы отобразить изменения на экране, вы должны выполнить setState(), поэтому при горячем обновлении sh изменения появляются.

Теперь у вас есть несколько вариантов, сначала вы можете взглянуть на FutureBuilder , это виджет, который будет строиться дважды: один раз до разрешения вашего Future и один раз после этого, это означает "автообновление". В этом случае ваш список данных станет типом Future, а ваш ListView будет обернут FutureBuilder, чтобы он был построен после того, как данные будут готовы.

Другой вариант - делать setState() каждый раз, когда вы добавляете элемент в Список имеющихся у вас объектов.

...