如何使用FutureBuilder在Build方法之外递增变量

时间:2020-06-29 03:22:17

标签: flutter

我有FutureBuilder,它会在我的第一时间使用数据。 数据是杂货项目清单以及价格和购买次数。 FutureBuilder在列表视图中显示它们。

我想做的是向用户显示此特定列表的总数。 因此,我在build方法之前初始化了一个double。 当listview遍历所有项目时,我将添加到double中以获取总计,然后将其显示在页面底部。

class _PreviousCartState extends State<PreviousCart> {
  Future<DocumentSnapshot> snapshot;

  @override
  void initState() {
    super.initState();
    snapshot = FirestoreAPI.getWithDate(widget.date);
  }

  double total = 0;

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.white,
      child: Column(
        children: [
          Expanded(
            flex: 12,
            child: FutureBuilder(
                future: snapshot,
                builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.waiting:
                      return Center(child: CircularProgressIndicator());
                    default:
                      if (snapshot.hasData) {
                        if(snapshot.data.data.length == 0) {
                          return  AlertDialog(
                            content: Text('Wrong Date', textAlign: TextAlign.center, style: TextStyle(color: Colors.black)),
                            backgroundColor: Colors.redAccent,
                            actions: [Icon(Icons.keyboard_backspace)],
                          );
                      }
                        List<dynamic> items = snapshot.data.data['items'];
                        
                    return ListView.builder(
                      itemCount: items.length + 1,
                      itemBuilder: (context, index) {
                        if (index == 0) {
                          return Container(
                            margin: EdgeInsets.all(10),
                            padding: EdgeInsets.all(7),
                            child: Row(
                              children: [
                                Text('Number'),
                                Text('Name'),
                                Text('Price')
                              ],
                              mainAxisAlignment:
                                  MainAxisAlignment.spaceBetween,
                            ),
                          );
                        }
                        index--;
                        final currentItem = items[index];

                        this.total += currentItem['price'] * currentItem['count']; // HERE
                        print('LOOK AT ME $this.total'); // HERE

                        return Card(
                          child: ListTile(
                            leading: Text('${index + 1}'),
                            title: Center(child: Text(currentItem['name'])),
                            subtitle: Center(
                                child: Text(
                                    '''Bought ${currentItem["count"]} times for a total of ${currentItem['price'] * currentItem["count"]} dirhams''')),
                            trailing: Text('${currentItem["price"]} Dhs'),
                          ),
                        );
                      },
                    );
                  } else
                    return Text(snapshot.error.toString());
              }
            }),
      ),
      Expanded(
          flex: 1, child: Center(child: Text('Total:   ${this.total}'))),
    ],
  ),
);

} }

  1. 重新启动后,总数为0.0。
  2. 此后进行热装,显示正确的总数。
  3. 此后进行热装,显示正确总数的两倍。
  4. 然后是正确总数的3倍。

以此类推...

即使添加后的打印语句正确计数,也是如此。

请向我解释为什么会这样?

1 个答案:

答案 0 :(得分:2)

据我所知,您需要使用SetState。

setState(() { total += currentItem['price'] * currentItem['count']; });

根据docs

调用setState会通知框架此对象的内部状态已更改,该方式可能会影响此子树中的用户界面,这会导致框架为该State对象安排构建。

当触发setState时,它将重建视图并立即查看新状态暗含的更改。基本上就像是热装。