List Flatter SingleChildScrollView删除项目
我有以下代码,其中我生成了一个项目列表(数据取自Firebase)。我想实现删除项目的功能,但我不知道如何访问列表以及如何删除项目: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( .
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);
});
},
);