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;
}()),
);
您的列表正在通过您提供给 StreamBuilder
的 Stream
数据构建,请创建新列表,您需要更改 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);
});
},
);
您必须对索引执行相同的操作,但我认为这是一种更好的方法,因为子项对父项没有任何权力并且无法更改其状态,这是一种很好的做法。
我有以下代码生成项目列表(数据取自 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;
}()),
);
您的列表正在通过您提供给 StreamBuilder
的 Stream
数据构建,请创建新列表,您需要更改 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);
});
},
);
您必须对索引执行相同的操作,但我认为这是一种更好的方法,因为子项对父项没有任何权力并且无法更改其状态,这是一种很好的做法。