Flutter- 图像选择器包:通过删除操作一张一张地显示图像
Posted
技术标签:
【中文标题】Flutter- 图像选择器包:通过删除操作一张一张地显示图像【英文标题】:Fluter- Image picker package: show images one after another with delete action 【发布时间】:2020-06-19 06:47:44 【问题描述】:在我的 Flutter 公关项目中,我使用 Image Picker 插件从 android 移动图库中选择图像,或者用相机捕获图像并在每张图像下方使用删除图标依次显示它们。在点击RaisedButton
从图库中选择图像时,会调用方法imageSelectorGallery()
。在setState()
方法内部,我向List
添加了一个SizedBox
和一个delete
图标,即images_captured
。我希望images_captured
在SingleChildScrollView
中的Column
内呈现。
但是从图库中选择图像后,什么也没有发生。我还想点击delete
图标并删除其上方的图像。但据我所知,flutter 没有数据绑定机制可以将图像与删除按钮关联起来。
代码如下:
class PrescriptionScreen extends StatefulWidget
@override
State<StatefulWidget> createState()
return new UserOptionsState();
class UserOptionsState extends State<PrescriptionScreen>
//save the result of gallery fileUserOptions
File galleryFile;
//save the result of camera file
File cameraFile;
@override
Widget build(BuildContext context)
var images_captured=List<Widget>();
//display image selected from gallery
imageSelectorGallery() async
galleryFile = await ImagePicker.pickImage(
source: ImageSource.gallery,
// maxHeight: 50.0,
// maxWidth: 50.0,
);
print("You selected gallery image : " + galleryFile.path);
setState(()
var sized_box_indiv= new SizedBox(
height: 200.0,
width: 300.0,
//child: new Card(child: new Text(''+galleryFile.toString())),
//child: new Image.file(galleryFile),
child: galleryFile == null
? new Text('Sorry nothing selected from gallery!!')
: new Image.file(galleryFile),
);
images_captured.add(sized_box_indiv);
var delete_button = IconButton(icon: Icon(Icons.delete), onPressed: () );
images_captured.add(delete_button);
);
//display image selected from camera
imageSelectorCamera() async
cameraFile = await ImagePicker.pickImage(
source: ImageSource.camera,
//maxHeight: 50.0,
//maxWidth: 50.0,
);
print("You selected camera image : " + cameraFile.path);
setState(() );
return new SingleChildScrollView(
child:Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new RaisedButton(
child: new Text('Select Image from Gallery'),
onPressed: imageSelectorGallery,
),
new RaisedButton(
child: new Text('Select Image from Camera'),
onPressed: imageSelectorCamera,
),
Column(
children: images_captured
),
],
),
);
/* ,
),
);*/
Q1:如何在每张图片下方分别显示delete
图标按钮从图库中选择的图片?
Q2:点击delete
图标按钮如何删除对应的图片?
我想如果我可以为画廊做到这一点,我也可以为相机拍摄做到这一点......
编辑:
我使用jJuice
的答案,选择后的图像显示溢出错误。截图如下:
我的代码是:
class UserOptionsState extends State<PrescriptionScreen>
//save the result of gallery fileUserOptions
File galleryFile;
//save the result of camera file
File cameraFile;
var images_captured=List<Widget>();
List<File> images = List<File>();
@override
Widget build(BuildContext context)
//display image selected from gallery
imageSelectorGallery() async
galleryFile = await ImagePicker.pickImage(
source: ImageSource.gallery,
// maxHeight: 50.0,
// maxWidth: 50.0,
);
images.add(galleryFile);
print("You selected gallery image : " + galleryFile.path);
setState(()
);
//display image selected from camera
imageSelectorCamera() async
cameraFile = await ImagePicker.pickImage(
source: ImageSource.camera,
//maxHeight: 50.0,
//maxWidth: 50.0,
);
print("You selected camera image : " + cameraFile.path);
setState(() );
return new SingleChildScrollView(
child:Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new RaisedButton(
child: new Text('Select Image from Gallery'),
onPressed: imageSelectorGallery,
),
new RaisedButton(
child: new Text('Select Image from Camera'),
onPressed: imageSelectorCamera,
),
new Container(
// new Column(
// children: <Widget>[
height: 1200,
child:GridView.count(
crossAxisSpacing: 6,
mainAxisSpacing: 6,
crossAxisCount: 3,
children: List.generate(images.length, (index)
return Column(
children: <Widget>[
Container(
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: ClipRRect(
child: Image.file(images[index], fit: BoxFit.cover),
borderRadius: BorderRadius.circular(10),
)
),
GestureDetector(
onTap: ()
setState(()
images.removeAt(index);
);
,
child: Padding(
padding: const EdgeInsets.all(3.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Icon(Icons.clear, color: Colors.black, size: 20),
),
),
),
]
);
),
),
// ]
)
/*displaySelectedFile(galleryFile),
displaySelectedFile(cameraFile)*/
],
),
);
Widget displaySelectedFile(File file)
return new SizedBox(
height: 200.0,
width: 300.0,
//child: new Card(child: new Text(''+galleryFile.toString())),
//child: new Image.file(galleryFile),
child: file == null
? new Text('Sorry nothing selected!!')
: new Image.file(file),
);
【问题讨论】:
如果你想加载多张图片可以使用这个插件pub.dev/packages/multi_image_picker。看看它是否有效,或者您需要更多帮助。 我的方法有什么问题? 使用您的方法,您只能拥有一台相机和一张画廊图片,因为您为每个使用一个实例。您可以使用页面视图显示它们,对于单个页面,您可以使用带有删除图标的堆栈。 新图像被添加到“images_captured”列表中。那他们为什么不出现呢?连一张图片都没有出现?您可以用您的方法发布答案,即:堆栈等吗?删除操作将如何发生? 您的图像列表是空的,因为它在构建函数中,并且每次获得图像时,您都会调用 setState 函数,该函数再次调用构建函数并且您的图像列表会再次创建。尝试将var images_captured=List<Widget>()
放在构建函数之外,您将获得所有图像。
【参考方案1】:
问题 1:您首先需要将使用 ImagePicker(或 MultiImagePicker 插件)拾取的图像存储在一个集合中。这是一个关于如何做到这一点的示例:
List<File> images = List<File>();
images.add(await ImagePicker.pickImage(source: ImageSource.gallery, imageQuality: 20););
当您想在屏幕上显示这些图像时,您可以使用几个不同的小部件,例如 ListView、GridView、Row、Column。 这是我使用 GridView 的示例:
child: Container(
height: 1200,
child: GridView.count(
crossAxisSpacing: 6,
mainAxisSpacing: 6,
crossAxisCount: 3,
children: List.generate(images.length, (index)
return Column(
children: <Widget>[
Container(
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: ClipRRect(
child: Image.file(images[index], fit: BoxFit.cover),
borderRadius: BorderRadius.circular(10),
)
),
GestureDetector(
onTap: ()
setState(()
images.removeAt(index);
);
,
child: Padding(
padding: const EdgeInsets.all(3.0),
child: Align(
alignment: Alignment.bottomCenter,
child: Icon(Icons.clear, color: Colors.white, size: 20),
),
),
),
]
),
),
),
我认为在这种情况下使用Stack
小部件效果最好。堆栈可用于显示小部件,彼此层叠。所以在这种情况下,一个显示图像的小部件,顶部有一个图标小部件,它是您的删除操作的按钮。
问题 2:
您可以通过调用列表等集合上可用的removeAt
方法来删除图像。请参阅GestureDetector
的onTap
方法内的代码。通过调用setState
,一旦图像被删除,页面就会被重建。
编辑
抱歉,我误读了您的问题,发现您想在图像下方显示一个按钮,而不是在其顶部。 Column
小部件可用于此目的。我相应地编辑了代码。
【讨论】:
如何在点击删除按钮时显示带有是和否选项的警报? 不是直接删除图像,而是调用一个显示警报消息的函数。 ***.com/questions/53844052/… 您的以child:
开头的代码应该放在哪里? Container
有height:1200
,上传很多图片后,出现溢出错误。除了上传单张图片,还有溢出错误Icons.clear
不显示?
这段代码只是为了让您了解如何实现它,我不会直接复制它。我猜将清除图标的颜色从白色更改为黑色会使其可见?如果您发布代码,我可以检查您如何解决溢出错误。
删除该部分后,我将您的代码粘贴到代码中 Column( children: images_captured ),
的位置。以上是关于Flutter- 图像选择器包:通过删除操作一张一张地显示图像的主要内容,如果未能解决你的问题,请参考以下文章
如何通过单击swift4中的addImage按钮将图像一张一张添加到tableviewcell中
如何使用Objective C以2秒的间隔一张一张地自动滚动图像?
如何将 UICollectionView Image 一张一张删除