Я создаю приложение, которое подключается и отправляет запросы на 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)
],
)
],
)
]),
)
)
);
}
);
}
}
Я получаю объект будущего, а не объект списка.
Код, используемый для отображения элементов:
Column(
children: response,
),
Как я могу получить список из этого метода и отобразить вывод?
Проблема в том, что getPizzas()
является асинхронным, то есть возвращает Future
. То, что вам требуется, по сути означает, что вы должны вместо этого изменить код рендеринга на это:
Column(
children: pizzasElements,
),
Так как вы, кажется, устанавливаете pizzaElements
чтобы он содержал ваш список виджетов.
Что вам нужно сделать, это отделить метод сборки от запроса. Поэтому в вашей функции сборки просто вызовите getPizzas()
и забудьте об этом. Вот так:
Widget build(BuildContext context) {
getPizzas();
return MaterialApp(...
Далее необходимо убедиться, что pizzaElements инициализирован и вместо этого является свойством класса, а не локальной переменной. Так что это будет означать, что вам нужно использовать StatefulWidget
и это будет происходить в классе State.
List<Widget> pizzaElements = <Widget>[];
Затем в getPizzas()
вам нужно убедиться, что вы вызываете setState
, чтобы ваши виджеты повторно отображались со списком:
Future<List<Widget>> getPizzas() async {
await 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;
});
});
});
}