我已经通过从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),
),
);
},
),
),
);
}
}
发生的事情是,在将数据添加到列表之前,正在加载屏幕,这是因为getData函数是异步的。因此,当您的屏幕首次加载时,列表为空,并且您可能知道为了在屏幕上显示更改,您必须执行setState()
,这就是为什么在热刷新时显示更改的原因。
现在您在这里有多个选项,首先您可以看一下FutureBuilder,这是一个将生成两次的窗口小部件,一次在Future
解析之前,一次在此之后,意味着它“自动刷新”。在这种情况下,您的数据列表将成为Future类型,并且ListView将被FutureBuilder包装,以便在数据准备好之后将其构建。