Как программно добавить виджеты списка на панель вкладок?

#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. Я понимаю. Редактирование моего ответа.