如何以编程方式将列表小部件添加到TabBar?

时间:2019-04-17 17:39:32

标签: android dart flutter 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 个答案:

答案 0 :(得分:1)

问题在于getPizzas()是异步的,这意味着它返回了Future。本质上,您所需要的意味着您应该改为将渲染代码更改为此:

Column(
  children: pizzasElements,
),

由于您似乎要设置pizzaElements来包含小部件列表。

更新:

您需要做的是将构建方法与请求分开。因此,在您的构建函数中,只需调用getPizzas()函数,而不必理会它。像这样:

Widget build(BuildContext context) {
    getPizzas();
    return MaterialApp(...

接下来,您需要确保pizzaElements已初始化并且是类属性,而不是局部变量。因此,这意味着您需要使用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;
      });
    });
  });
}