flutter SingleChildScrollView 删除项目

flutter SingleChildScrollView remove item

我有以下代码生成项目列表(数据取自 Firebase)。我想实现删除项目的功能,但我不知道如何访问列表以及如何删除项目:

class _MyOfferState extends State<MyOffer> {
  List<Widget> items = [];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
...
          body: SingleChildScrollView(
            child: Column(
              children: [
                StreamBuilder<QuerySnapshot>(
                  stream: FirebaseFirestore.instance
                      .collection('Offers')
                  builder: (BuildContext context, snapshot) {
                      snapshot.data.docs.forEach((element) {
                        element.get('items').forEach((item) {
                          String _name = element['name'];
                          String _category = item['category'];

                          items.add(offer(name, category, context,...));

                        });
            }
                      );
                    }
                    return new Column(
                      children: List.unmodifiable(() sync* {
                        yield* items;
                      }()),
                    );
                  },
          ),
        
  }
}

这是一个动态 class,我有 GestureDetector。当用户点击它时,该项目应该被删除。

dynamic offer(name, category, context,) {

  return GestureDetector(
      child: Container(
        child: Row(
                    children: [
                      Text(name),
                      Text(category),
          ],
        ),
      ),
    ),
    onTap: () {
      
 // remove item should be here
    },
  );
}

您需要传递项目的索引并按索引删除:

int index = 0;
snapshot.data.docs.forEach((element) {
                        element.get('items').forEach((item) {
                          String _name = element['name'];
                          String _category = item['category'];

                          items.add(offer(index, name, category, context,...));
                          index++;
                        });



Widget offer(int index, string name, string category, BuildContext context,) {

  return GestureDetector(
      child: Container(
        child: Row(
                    children: [
                      Text(name),
                      Text(category),
          ],
        ),
      ),
    ),
    onTap: () {
      
 // remove item should be here
items.removeAt(index);
setState((){});
    },
  );
}

            }
                      );
                    }
                    return new Column(
                      children: List.unmodifiable(() sync* {
                        yield* items;
                      }()),
                    );

您的列表正在通过您提供给 StreamBuilderStream 数据构建,请创建新列表,您需要更改 Stream 值,我建议保留 FirebaseFirestore.instance.collection('Offers') 实例在流中并修改流。

    class _MyOfferState extends State<MyOffer> {
      List<Widget> items = [];
StreamController _controller = StreamController();

 @override
  void initState() {
    super.initState();
_controller.addStream( FirebaseFirestore.instance
                      .collection('Offers').snapshots());    
  }


// dont forgot to close stream
 @override
  void dispose() {
    _controller.close();
    super.dispose();
  }


      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
    ...
                  body: SingleChildScrollView(
                    child: Column(
                      children: [
                        StreamBuilder<QuerySnapshot>(
                          stream: _controller.stream,
                          builder: (BuildContext context, snapshot) {
                              snapshot.data.docs.forEach((element) {
                                element.get('items').forEach((item) {
                                  String _name = element['name'];
                                  String _category = item['category'];
        
                                  items.add(offer(name, category, context,(){
// remove function is here
  snapshot.data.docs.removeWhere((e) => e.id == element.id);
 _controller.add(snapshot.data);
});
      


                            });
                }
                          );
                        }
                        return new Column(
                          children: List.unmodifiable(() sync* {
                            yield* items;
                          }()),
                        );
                      },
              ),
            
      }
    }

同时将 onTap 传递给您的小部件函数

dynamic offer(name, category, context, onTap) {

  return GestureDetector(
      child: Container(
        child: Row(
                    children: [
                      Text(name),
                      Text(category),
          ],
        ),
      ),
    ),
    onTap: onTap,
  );
}

从内部删除要约并不是最佳做法,但您可以通过多种方式实现。我能想到的第一个是传递一个函数,在创建报价时将其删除,如下所示:

items.add(offer(name, category, context,..., () {
   setState(() {
      FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
      items.remoev(index);
   });
}));

您需要事先创建索引并每次都增加它,但我不建议这样做。 我这样做的方法是将报价更改为:

dynamic offer(name, category, context,) {

  return Container(
        child: Row(
           children: [
              Text(name),
              Text(category),
          ],
        ),
      );
}

并且在创建报价时将其包装在 GestureDetector 中,如下所示:

items.add(GestureDetector(
             child: offer(name, category, context,...)),
             onTap: () {
                setState(() {
                    FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
                    items.remoev(index);
                });
             },
         );

您必须对索引执行相同的操作,但我认为这是一种更好的方法,因为子项对父项没有任何权力并且无法更改其状态,这是一种很好的做法。