删除一个元素总是删除颤动中的最后一个
deleting an element always delete the last one in flutter
List storedWishes = [
{
'title': 'Phone',
'description': 'a phone would be nice',
'price': 200.00,
'icon': Icon(Icons.phone)
},
{
'title': 'monitor',
'description': 'need it for a 2 screen setup',
'price': 350.00,
'icon': Icon(Icons.tv)
},
{
'title': 'headphones',
'description': 'need some high quality sound',
'price': 100.00,
'icon': Icon(Icons.headset)
},
];
final wishes = useState(storedWishes);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('iWant'),
),
body: Column(
//map the wishes to a list of wish widgets
children: wishes.value
.map((wish) => Wish(
title: wish['title'] as String,
description: wish['description'] as String,
price: wish['price'] as double,
icon: wish['icon'],
onDelete: () {
wishes.value.remove(wish)
wishes.notifyListeners();
},
))
.toList(),
)));
wish.dart代码:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class Wish extends HookWidget {
const Wish(
{Key? key,
this.title = 'default title',
this.description = 'default description',
this.price = 0.00,
this.icon = const Icon(Icons.star),
this.onDelete})
: super(key: key);
final String title;
final String description;
final double price;
final dynamic icon;
final VoidCallback? onDelete;
@override
Widget build(BuildContext context) {
var wishes = useState({
'title': title,
'description': description,
'price': price,
'image': icon
});
return Card(
child: Row(children: [
wishes.value['image'] as Icon,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(wishes.value['title'] as String),
Text(wishes.value['description'] as String),
],
),
),
Text((wishes.value['price'].toString()) + '$'),
Column(
children: [
Icon(Icons.edit),
IconButton(
onPressed: () {
onDelete!();
},
icon: Icon(Icons.delete),
)
],
),
]));
}
}
// child: Card(
// child: Row(children: [
// ,
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text('Product name'),
// Text('Product description'),
// ],
// ),
// Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Text('Price:'),
// Text('21$'),
// ],
// ),
// ])),
// );
当我点击删除任何其他元素时,点击删除按钮总是删除最后一个元素
edit1:我在点击删除图标后调试打印了数组,数组被正确编辑,但错误的小部件从屏幕上删除
这是一个视频:
https://drive.google.com/file/d/1bEjHh4utynZk3QzSWw5gWv__YcpqKkb2/view?usp=sharing
edit2:我已经从愿望小部件中删除了钩子,现在似乎可以正常工作了?无论如何感谢您的帮助:)
这是因为它实际上并没有根据元素的内容来识别元素。当您在列表上调用 remove
函数时,它会看到元素是一个 Map 对象,您的输入也是一个 Map 对象。所以它只是删除了最后一个元素。
您要做的是为每个愿望分配一个唯一标识符。像这样:
{
'id': '0'
'title': 'headphones',
'description': 'need some high quality sound',
'price': 100.00,
'icon': Icon(Icons.headset)
},
或者如果 title
对于每个项目都是唯一的,那么您也可以参考它。
然后简单地通过编辑你的删除函数做一个深入的比较:
onDelete: () {
wishes.value.removeWhere((e) => e["id"] == wish["id"]);
//OR
//wishes.value.removeWhere((e) => e["title"] == wish["title"]);
wishes.notifyListeners();
},
我不知道为什么它对你不起作用,但它对我来说很好用。因为我不知道你的愿望 class 是什么样子,所以我做了这样的:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(MyApp());
}
class MyApp extends HookWidget {
@override
Widget build(BuildContext context) {
List storedWishes = [
{
'title': 'Phone',
'description': 'a phone would be nice',
'price': 200.00,
'icon': Icon(Icons.phone)
},
{
'title': 'monitor',
'description': 'need it for a 2 screen setup',
'price': 350.00,
'icon': Icon(Icons.tv)
},
{
'title': 'headphones',
'description': 'need some high quality sound',
'price': 100.00,
'icon': Icon(Icons.headset)
},
];
final wishes = useState(storedWishes);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('iWant'),
),
body: Column(
//map the wishes to a list of wish widgets
children: wishes.value
.map((wish) => TextButton(
child: Text(wish['title'] as String),
onPressed: () {
wishes.value.remove(wish);
wishes.notifyListeners();
},
))
.toList(),
)));
}
}
它像这样正常工作。
编辑:我可以使用您的 Wish 代码重现您的问题。我实际上不熟悉 HookWidget,但将代码更改为此似乎可以修复它。我不知道 useState
的确切用途,但将其排除在外可以解决问题。你甚至可以让 Wish 只扩展 StatelessWidget 而不是 HookWidget
class Wish extends StatelessWidget {
const Wish(
{Key? key,
this.title = 'default title',
this.description = 'default description',
this.price = 0.00,
this.icon = const Icon(Icons.star),
this.onDelete})
: super(key: key);
final String title;
final String description;
final double price;
final dynamic icon;
final VoidCallback? onDelete;
@override
Widget build(BuildContext context) {
return Card(
child: Row(children: [
icon,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title),
Text(description),
],
),
),
Text((price.toString()) + '$'),
Column(
children: [
Icon(Icons.edit),
IconButton(
onPressed: onDelete,
icon: Icon(Icons.delete),
)
],
),
]));
}
}
List storedWishes = [
{
'title': 'Phone',
'description': 'a phone would be nice',
'price': 200.00,
'icon': Icon(Icons.phone)
},
{
'title': 'monitor',
'description': 'need it for a 2 screen setup',
'price': 350.00,
'icon': Icon(Icons.tv)
},
{
'title': 'headphones',
'description': 'need some high quality sound',
'price': 100.00,
'icon': Icon(Icons.headset)
},
];
final wishes = useState(storedWishes);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('iWant'),
),
body: Column(
//map the wishes to a list of wish widgets
children: wishes.value
.map((wish) => Wish(
title: wish['title'] as String,
description: wish['description'] as String,
price: wish['price'] as double,
icon: wish['icon'],
onDelete: () {
wishes.value.remove(wish)
wishes.notifyListeners();
},
))
.toList(),
)));
wish.dart代码:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class Wish extends HookWidget {
const Wish(
{Key? key,
this.title = 'default title',
this.description = 'default description',
this.price = 0.00,
this.icon = const Icon(Icons.star),
this.onDelete})
: super(key: key);
final String title;
final String description;
final double price;
final dynamic icon;
final VoidCallback? onDelete;
@override
Widget build(BuildContext context) {
var wishes = useState({
'title': title,
'description': description,
'price': price,
'image': icon
});
return Card(
child: Row(children: [
wishes.value['image'] as Icon,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(wishes.value['title'] as String),
Text(wishes.value['description'] as String),
],
),
),
Text((wishes.value['price'].toString()) + '$'),
Column(
children: [
Icon(Icons.edit),
IconButton(
onPressed: () {
onDelete!();
},
icon: Icon(Icons.delete),
)
],
),
]));
}
}
// child: Card(
// child: Row(children: [
// ,
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text('Product name'),
// Text('Product description'),
// ],
// ),
// Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Text('Price:'),
// Text('21$'),
// ],
// ),
// ])),
// );
当我点击删除任何其他元素时,点击删除按钮总是删除最后一个元素
edit1:我在点击删除图标后调试打印了数组,数组被正确编辑,但错误的小部件从屏幕上删除
这是一个视频: https://drive.google.com/file/d/1bEjHh4utynZk3QzSWw5gWv__YcpqKkb2/view?usp=sharing
edit2:我已经从愿望小部件中删除了钩子,现在似乎可以正常工作了?无论如何感谢您的帮助:)
这是因为它实际上并没有根据元素的内容来识别元素。当您在列表上调用 remove
函数时,它会看到元素是一个 Map 对象,您的输入也是一个 Map 对象。所以它只是删除了最后一个元素。
您要做的是为每个愿望分配一个唯一标识符。像这样:
{
'id': '0'
'title': 'headphones',
'description': 'need some high quality sound',
'price': 100.00,
'icon': Icon(Icons.headset)
},
或者如果 title
对于每个项目都是唯一的,那么您也可以参考它。
然后简单地通过编辑你的删除函数做一个深入的比较:
onDelete: () {
wishes.value.removeWhere((e) => e["id"] == wish["id"]);
//OR
//wishes.value.removeWhere((e) => e["title"] == wish["title"]);
wishes.notifyListeners();
},
我不知道为什么它对你不起作用,但它对我来说很好用。因为我不知道你的愿望 class 是什么样子,所以我做了这样的:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(MyApp());
}
class MyApp extends HookWidget {
@override
Widget build(BuildContext context) {
List storedWishes = [
{
'title': 'Phone',
'description': 'a phone would be nice',
'price': 200.00,
'icon': Icon(Icons.phone)
},
{
'title': 'monitor',
'description': 'need it for a 2 screen setup',
'price': 350.00,
'icon': Icon(Icons.tv)
},
{
'title': 'headphones',
'description': 'need some high quality sound',
'price': 100.00,
'icon': Icon(Icons.headset)
},
];
final wishes = useState(storedWishes);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('iWant'),
),
body: Column(
//map the wishes to a list of wish widgets
children: wishes.value
.map((wish) => TextButton(
child: Text(wish['title'] as String),
onPressed: () {
wishes.value.remove(wish);
wishes.notifyListeners();
},
))
.toList(),
)));
}
}
它像这样正常工作。
编辑:我可以使用您的 Wish 代码重现您的问题。我实际上不熟悉 HookWidget,但将代码更改为此似乎可以修复它。我不知道 useState
的确切用途,但将其排除在外可以解决问题。你甚至可以让 Wish 只扩展 StatelessWidget 而不是 HookWidget
class Wish extends StatelessWidget {
const Wish(
{Key? key,
this.title = 'default title',
this.description = 'default description',
this.price = 0.00,
this.icon = const Icon(Icons.star),
this.onDelete})
: super(key: key);
final String title;
final String description;
final double price;
final dynamic icon;
final VoidCallback? onDelete;
@override
Widget build(BuildContext context) {
return Card(
child: Row(children: [
icon,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title),
Text(description),
],
),
),
Text((price.toString()) + '$'),
Column(
children: [
Icon(Icons.edit),
IconButton(
onPressed: onDelete,
icon: Icon(Icons.delete),
)
],
),
]));
}
}