Reputation: 603
In my flutter app, I have implemented an image picker from the gallery and reordering. Now I want to implement 'delete' function when the user tap on each image displayed on the screen. So, I simply used 'removeAt(index)' but it always delete higest index image in the list as all images keep their index position as the length of the array of images. Can anybody help me with how to implement the delete function properly?
This is the code :
final List<XFile>? _imageList = [];
final imagePicker = ImagePicker();
final Logger log = LoggerService.logger('ImageUpload');
FirebaseDao firebasDao = locator.get<FirebaseDao>();
late final Map<String, dynamic> _newImgList = <String, dynamic>{};
int i = 0;
late List<Widget> _tiles;
Future pickImage() async {
final List<XFile>? pick = await imagePicker.pickMultiImage(
maxWidth: 640, maxHeight: 480, imageQuality: 50);
setState(() {
if (pick != null) {
_imageList!.clear();
_imageList!.addAll(pick);
for (XFile img in _imageList!) {
_tiles.add(Container(
child: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
setState(() {
_tiles.removeAt(i);
});
},
),
height: 50,
width: 50,
margin: const EdgeInsets.all(3),
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.scaleDown, image: FileImage(File(img.path))),
),
));
_newImgList.putIfAbsent(i.toString(), () => img);
i++;
}
} else {
showSnackBar(
context, 'No image selected', const Duration(microseconds: 1000));
}
});
}
Future uploadImage() async {
Reference ref;
int count = 0;
int postId = DateTime.now().microsecondsSinceEpoch;
for (var key in _newImgList.keys) {
count++;
postId = postId + count;
ref = FirebaseStorage.instance
.ref()
.child('${firebasDao.getCurrentUser()!.uid}/posts')
.child(postId.toString());
await ref.putFile(File(_newImgList[key].path)).whenComplete(() async {
var url = await ref.getDownloadURL();
_newImgList.update(key, (value) => url);
});
}
}
showSnackBar(BuildContext context, String snackBarText, Duration d) {
final snackBar = SnackBar(content: Text(snackBarText), duration: d);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
@override
void initState() {
super.initState();
_tiles = <Widget>[
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
pickImage();
},
)
];
}
@override
Widget build(BuildContext context) {
void _onReorder(int oldIndex, int newIndex) {
setState(() {
Widget row = _tiles.removeAt(oldIndex);
_tiles.insert(newIndex, row);
var temp = _newImgList[(newIndex - 1).toString()];
_newImgList.update((newIndex - 1).toString(),
(value) => _newImgList[(oldIndex - 1).toString()]);
_newImgList.update((oldIndex - 1).toString(), (value) => temp);
});
}
var wrap = ReorderableWrap(
spacing: 8.0,
runSpacing: 4.0,
padding: const EdgeInsets.all(8),
children: _tiles,
onReorder: _onReorder);
var _imageGrid = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[wrap],
);
return Form(
key: _addItemFormKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 24.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(30.0)),
child: SizedBox(
height: 150,
width: double.infinity,
child: Column(
children: [
const SizedBox(
height: 10,
),
Expanded(
flex: 4,
child: SizedBox(
width: 400,
child: Center(
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(child: _imageGrid),
],
),
),
)),
],
)),
),
),
),
],
),
),
Upvotes: 0
Views: 949
Reputation: 4567
convert your foreach loop to a for loop with index
for (XFile img in _imageList!) { ...}
to
for (int index=0; _imageList.length; index++)
now you have an index for your remove call
_tiles.removeAt(index);
Upvotes: 1