#android #dart #flutter #android-asynctask #futuretask
#Android #dart #флаттер #android-asynctask #futuretask
Вопрос:
Я создаю приложение, которое подключается и отправляет запросы на HTTP-сервер, а когда получает ответы, анализирует их в объект JSON и отображает выходные данные. Проблема возникает, когда я использую следующий метод:
Future<List<Widget>> getPizzas() async {
List<Widget> pizzasElements;
await PizzeriaAPI().getMenu().then((response) {
Iterable list = json.decode(response.body);
var pizzas = list.map((model) => Pizza.fromJson(model)).toList();
pizzasElements =new List<Widget>.generate(pizzas.length, (int index){
Row row = new Row();
row.children.add(new Text(pizzas[index].name));
row.children.add(new Text("${pizzas[index].price} $"));
row.children.add(new MaterialButton(color: Colors.green,child: Text("Add"),onPressed: (){
// esegui il post
}));
return row;
});
});
}
Это метод сборки:
@override
Widget build(BuildContext context) {
getPizzas().then((List<Widget> response){
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.dark,
),
home: DefaultTabController(length: 4, child: Scaffold(
appBar: AppBar(
title: const Text('Pizzeria'),
bottom: TabBar(
isScrollable: true,
tabs: [
Tab(text: "Buy"),
Tab(text: "Orders"),
Tab(icon: Icon(Icons.shopping_cart)),
Tab(icon: Icon(Icons.settings))
]
),
),
body: TabBarView(children: [
Column(
children: response,
),
Column(
children: <Widget>[
Row(
children: <Widget>[
Text("Orders")
],
)
],
),
Column(
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.shopping_cart)
],
)
],
),
Column(
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.settings)
],
)
],
)
]),
)
)
);
}
);
}
}
Я получаю объект Future, а не объект List.
Код, используемый для отображения элементов:
Column(
children: response,
),
Как я могу получить список из этого метода и отобразить вывод?
Ответ №1:
Проблема в том, что getPizzas()
это асинхронно, то есть возвращает a Future
. То, что вам требуется, по сути, означает, что вместо этого вы должны изменить свой код рендеринга на это:
Column(
children: pizzasElements,
),
Поскольку вы, похоже, настраиваете pizzaElements
свой список виджетов.
Обновить:
Что вам нужно сделать, это отделить метод сборки от запроса. Итак, в вашей функции сборки просто вызовите getPizzas()
функцию и забудьте об этом. Вот так:
Widget build(BuildContext context) {
getPizzas();
return MaterialApp(...
Далее вам нужно убедиться pizzaElements
, что он инициализирован и является свойством класса, а не локальной переменной. Таким образом, это означало бы, что вам нужно будет использовать a StatefulWidget
, и это будет происходить в классе State.
List<Widget> pizzaElements = <Widget>[];
Затем getPizzas()
вам нужно убедиться, что вы вызываете setState
, чтобы ваши виджеты повторно отображались вместе со списком:
void getPizzas() {
PizzeriaAPI().getMenu().then((response) {
Iterable list = json.decode(response.body);
var pizzas = list.map((model) => Pizza.fromJson(model)).toList();
setState(() {
pizzasElements = new List<Widget>.generate(pizzas.length, (int index) {
Row row = new Row();
row.children.add(new Text(pizzas[index].name));
row.children.add(new Text("${pizzas[index].price} $"));
row.children.add(new MaterialButton(
color: Colors.green,
child: Text("Add"),
onPressed: () {
// esegui il post
}));
return row;
});
});
});
}
Комментарии:
1. Проблема остается той же, потому что как я могу установить синхронно pizzasElements с помощью метода getPizzas() в методе сборки?
2. Я понимаю. Редактирование моего ответа.