Как программно добавить List Widgets в TabBar?

1

Я создаю приложение, которое подключается и отправляет запросы на 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,
),

Как я могу получить список из этого метода и отобразить вывод?

Теги:
flutter
dart
android-asynctask
futuretask

1 ответ

1

Проблема в том, что 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;
      });
    });
  });
}
  • 0
    Проблема остается той же, потому что как я могу установить синхронно pizzasElements с методом getPizzas () в методе сборки?
  • 1
    Понимаю. Редактирование моего ответа.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню