Я передаю данные ответа API через FutureBuilder. У меня есть API, который дает мне название, содержание и другую конечную точку для ссылки на миниатюру. В моем коде мои списки нуждаются в thumnail и заголовке. Поэтому я в первый раз вызываю API и получаю заголовок, содержимое и пустую ссылку в моем конструкторе User, когда мои userData заполняются первым вызовом API, он отображает заголовок в списке без ожидания thumnail. Затем я вызываю оператор whencomplete в функции init, чтобы вызвать второй API для получения ссылки thumnail. второй вызов API получить изображения, а затем я обновляю пользовательский объект класса User, который является глобальным объектом. но Future Builder не уведомляет об изменении данных, тогда я использую SetState для уведомления о том, что пользовательские данные были изменены. Но дублируемый элемент заполняется в списке, который будет в будущем. почему это делает дублирование? Как справиться с этим, используя Futurebuidler при изменении данных?
return Scaffold(
body: Container(
child: FutureBuilder<List<User>>(
future: userData,
initialData: null,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
break;
case ConnectionState.done:
if (!snapshot.hasData) {
return Center(
child: ListTile(
title: Text("Loading ...",
style:
TextStyle(fontSize: 20, color: Colors.red))),
);
} else {
return ListView.separated(
itemCount: snapshot.data.length,
separatorBuilder: (BuildContext context, int index) =>
Divider(),
itemBuilder: (BuildContext context, index) {
return Card(
child: ListTile(
title: Text(snapshot.data[index].title.toString()),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
DetailPage(snapshot.data[index])));
},
leading:
snapshot.data[index].links.toString().isEmpty
? CircularProgressIndicator()
: Image.network(snapshot.data[index].links),
trailing: Icon(Icons.keyboard_arrow_right),
));
});
}
break;
default:
return Container();
}
}),
),
);
Вот функция инициализации
@override
void initState() {
userData = getUsers().whenComplete(() {
getImages();
});
super.initState();
}
Вот мой первый вызов APi
Future<List<User>> getUsers() async {
var data =
await http.get("https://primest.tv/wp-json/wp/v2/posts?per_page=1");
var jsonDataText = json.decode(data.body);
linksArray.clear();
int o=0;
for (var u in jsonDataText) {
String title = u["title"]['rendered'];
String content = u["content"]['rendered'];
String maper = u["_links"]['wp:featuredmedia'][0]["href"];
linksArray.add(maper);
User userr = User(title, content, '');
user.add(userr);
o++;
}
return user;
}
Вот мой второй API для thumnails
Future<List<User>> getImages() async {
int i = 0;
for (var userDataItem in linksArray) {
var data2 = await http.get(userDataItem);
var jsonData2 = json.decode(data2.body);
String imageLink = jsonData2["link"];
user.insert(i, User(user[i].title, user[i].content, imageLink));
i++;
}
// использующий setState для обновления данных в будущем сборщике setState (() {user = user;}); возвратный пользователь; }
Вот класс пользователя
class User {
String title, content, links;
User(this.title, this.content, this.links);
User.from(String link) {
this.links = link;
}
}