颤抖-运营价值流失

时间:2019-07-30 14:57:40

标签: asynchronous flutter dart google-cloud-firestore

我正在尝试捕获Firebase集合中的条目列表。对于从集合中获得的每个值,我创建一个带有两个按钮的ListTile小部件,以增加或减少我要在当前请求中添加的项目数量,每个ListTile都有一个对应的计数器。到目前为止,所有这些工作都已经完成,因为我已经能够正确渲染这些小部件及其按钮。问题是,一旦这两个函数退出,我在onPressed和setState函数中的计数器增量就会立即丢失。我知道计数器已经增加或减少,因为我可以正确打印该值。

这是我与朋友一起做的一个项目,目的是更好地了解Flutter的内部工作原理。我目前正在尝试使用Map,以便我可以通过直接引用要更改其计数器的产品名称来访问计数器值,但是这种方法似乎不起作用。我还尝试将每个产品存储在一个列表中,然后线性浏览每个产品,直到找到一个名称与我当前产品匹配的产品,尽管出于某种原因,这似乎行得通,但我敢肯定这不是最有效的产品一种高效的方法,因为我计划将来添加数千种不同的产品。

class AddEditRequests extends StatefulWidget {
  //...
}

class Product {
  String name;
  int amount;
  Product(this.name, this.amount);
  int incrementAmount () { /*...*/}

  int decrementAmount () { /*...*/}
}

class _AddEditRequestsState extends State<AddEditRequests> {

  bool isToGo = false;
  double summedPrice = 0;

  Map<String, Product> products;
  List<Product> listProducts;

  Widget buildListItem (BuildContext context, DocumentSnapshot document) {

    // Some very unsightly code, that for some reason works to a limited degree...
    listProducts.add(Product(document['nome'], 0));
    products[listProducts.where((value) => value.name == document['nome']).first.name] = listProducts.where((value) => value.name == document['nome']).first.amount;

    // What I wanted to do,and failed
    //products[document['nome']] = Product(document['nome'], 0);

    return Padding(
      child: ListTile(
        //...
        subtitle: Text("(${products[document['nome']].amount})", style: Theme.of(context).textTheme.subtitle,),
        trailing: Row(
          //...
          children: <Widget>[
            RawMaterialButton(
              //...
              onPressed: () {
                setState(() {
                  // What I originally inteded to do:
                  //products[document['nome']].incrementAmount();

                  // What works, but is very bad:
                  listProducts.where( (value) => value.name == document['nome']).first.incrementAmount();

                  // Something else I tried to do:
                  //products[document['nome']] += 1;

                  // If I directly try to use a map, the amount is incremented, but as soon as the function exits, it's decremented.
                  print(this.products[document['nome']].amount);
                });
              },
              child: Icon(Icons.add, color: Colors.white,),
            ),
            RawMaterialButton(
              //...
              onPressed: () {
                setState(() {
                  // Same as above
                });
              },
              child: Icon(Icons.remove, color: Colors.white,),
            ),
          ],
        ),
      )
    );
  }

  @override
  void initState() {
    products = Map();
    listProducts = List();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //...
      ),
      body: Container(
        //...
        ),
        child: SingleChildScrollView(
          child: Center(
            child: Column(
              children: <Widget>[
                //...
                //...
                //...
                StreamBuilder(
                  stream: Firestore.instance.collection("produtos").snapshots(),
                  builder: (context, snapshot) {
                    if (!snapshot.hasData) {
                      return CircularProgressIndicator();
                    }
                    return ListView.separated(
                      scrollDirection: Axis.vertical,
                      shrinkWrap: true,
                      itemCount: snapshot.data.documents.length,
                      itemBuilder: (context, index) {
                        return buildListItem(context, snapshot.data.documents[index]);
                      },
                      separatorBuilder: (BuildContext context, int index) {
                        return Divider(
                          endIndent: MediaQuery.of(context).size.width*0.07,
                          indent: MediaQuery.of(context).size.width*0.2,
                          color: Theme.of(context).dividerColor,
                          height: 10.0,
                        );
                      },
                    );
                  },
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

我希望单击我的RawMaterialButtons将为映射或列表中的特定条目调用crementAmount函数,并永久保留该值,而不是丢失它。另外,我不需要遍历整个列表来调用该函数,就我所知,我宁愿使用一个映射,因为它的效率更高。

编辑:我试图利用列表对上述代码进行一些补充,以显示每种产品的总价,但无济于事。对我可能做错的事有任何想法吗?

0 个答案:

没有答案