Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Flatter SingleChildScrollView删除项目_List_Flutter_Dart_Singlechildscrollview - Fatal编程技术网

List Flatter SingleChildScrollView删除项目

List Flatter SingleChildScrollView删除项目,list,flutter,dart,singlechildscrollview,List,Flutter,Dart,Singlechildscrollview,我有以下代码,其中我生成了一个项目列表(数据取自Firebase)。我想实现删除项目的功能,但我不知道如何访问列表以及如何删除项目: class _MyOfferState extends State<MyOffer> { List<Widget> items = []; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( .

我有以下代码,其中我生成了一个项目列表(数据取自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;
                      }()),
                    );
                  },
          ),
        
  }
}

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

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;
                      }()),
                    );

您的列表正在通过
Stream
数据生成您提供给
StreamBuilder
的数据,如果您需要更改流值,请创建新列表,我建议将
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;
                          }()),
                        );
                      },
              ),
            
      }
    }

由于您是streambuilder,因此它可以自动检测数据库中的更改并更新应用程序中的更改,您无需调用刷新应用程序的方法来应用更改

从服务本身中删除服务并不是最佳做法,但您可以通过多种方式完成。我能想到的第一个方法是传递一个函数,该函数在创建报价时将其删除,如下所示:

items.add(offer(name, category, context,..., () {
   setState(() {
      FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
      items.remoev(index);
   });
}));
items.add(GestureDetector(
             child: offer(name, category, context,...)),
             onTap: () {
                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(offer(name, category, context,..., () {
   setState(() {
      FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
      items.remoev(index);
   });
}));
items.add(GestureDetector(
             child: offer(name, category, context,...)),
             onTap: () {
                setState(() {
                    FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
                    items.remoev(index);
                });
             },
         );


<>你必须对索引做同样的事情,但是我认为这是一个更好的方法,因为孩子对父没有能力,不能改变它的状态,这是一个很好的实践。

你是否已经在ListVIEW中显示了数据?如果没有,请尝试创建listview.builder如果要从列表中删除特定项,请调用items.removeAt(索引)。如果您需要更具体的信息,请告诉我们-您到底想从列表中删除什么?从类动态提供中,我需要以某种方式确定列表中的哪个项目被单击,然后从列表中删除该项目,然后重新生成SingleChildScrollViewOk,使用listview.builder显示项目列表,在itemBuilder参数中可以找到通过以下方式单击的项目:(上下文,索引){return GestureDetector(child:Container(),onTap:(){print(items[index])}}从原始结构中,您想删除FirebaseFirestore上的数据,对吗?该流已经监听Firestore上的任何更改并重建自身。感谢您的回答。但我不知道如何将课堂上的设置状态称为“offer”。我得到一个错误:setState()在构造函数中调用:_MyOfferState 359b(生命周期状态:已创建,没有小部件,未装入)为什么不在类中作为小部件进行动态更新_MyOfferState,updated如果我按照您的建议进行操作,而不是删除元素,我会在屏幕上看到其他元素。看起来它不会从列表中删除元素,但会进行一些复制。
items.add(GestureDetector(
             child: offer(name, category, context,...)),
             onTap: () {
                setState(() {
                    FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
                    items.remoev(index);
                });
             },
         );