欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义组件获取本地图片和相机拍照图片

程序员文章站 2024-02-21 19:32:46
ios中有封装好的选择图片后长按出现动画删除效果,效果如下    而android找了很久都没有找到有这样效果的第三方组件,最后懒得找了还是...

ios中有封装好的选择图片后长按出现动画删除效果,效果如下 

Android自定义组件获取本地图片和相机拍照图片 

而android找了很久都没有找到有这样效果的第三方组件,最后懒得找了还是自己实现这效果吧

选择图片后还可对图片进行剪裁 

Android自定义组件获取本地图片和相机拍照图片

当然,代码中还有很多不完善的地方,我接下来会继续完善这个组件的
已经上传到开源社区,欢迎大家来star啊~

demo源码:传送门

设计中的碰到的一些问题和解决思路

1.如何让加号图片显示在gridview最后面

首先在调用gridadapter构造方法时就加载加号图片

 /**
 * 图片适配器
 * @param context 上下文
 * @param imagesum 最大可添加图片数
 */
 public gridadapter(context context, int imagesum) {
 this.context = context;
 this.imagesum = imagesum;
 // 加号图片
 maddbitmap = bitmapfactory.decoderesource(context.getresources(), r.drawable.ic_add_image);
 }

然后在getcount()方法里对图片数据集合加1,在该位置上添加加号图片

 @override
 public int getcount() {
 // 数据集合加一,在该位置上添加加号
 return imageitemdata == null ? 0 : imageitemdata.size() + 1;
 }

最后在getview()方法中,每次显示图片时都对数据集合中的元素数量进行判断,如果数据集合的数量大于position,则表示需要显示加号图片

 if (imageitemdata != null && imageitemdata.size() > position) {
 // 正常图片
 } else {
 // 加号图片
 }

这样就能保证加号图片一直在gridview最后一个item上

2.如何显示出删除按钮

在item布局时,在图片的右上角覆盖一层删除按钮,在adapter中对这个图片的显示和隐藏进行处理

/** 判断是否显示清除按钮 true=显示 */
 private boolean showimageclear = false;
 //对外提供显示和隐藏的方法
 /**
 * 设置图片显示状态
 * @param clear 图片状态
 */
 public void setclearimgshow(boolean clear) {
 showimageclear = clear;
 }

 /**
 * 图片显示状态
 * @return 状态 true=显示
 */
 public boolean getclearimgshow() {
 return showimageclear;
 }

删除按钮默认不显示,当用户长按图片时就显示出来

// 长按显示删除按钮
mgridview.setonitemlongclicklistener(new adapterview.onitemlongclicklistener() {
 @override
 public boolean onitemlongclick(adapterview<?> parent, view view, int position, long id) {
 if (!(position == gridadapter.imageitemdata.size())) {
 // 如果删除按钮已经显示了则不再设置
 if (!gridadapter.getclearimgshow()) {
 gridadapter.setclearimgshow(true);
 gridadapter.notifydatasetchanged();
 }
 }
 // 返回true,停止事件向下传播
 return true;
 }
});

这里需要拦截长按点击事件,把返回值设置为true,因为我们还设置了点击事件的监听,如果不拦截事件,那么长按事件结束后还会同时执行单击事件

最后关键的一点,在gridadapter类中的getview方法里进行控制,通过getclearimgshow方法获取删除图片是否需要显示,如果返回为true则显示出来,并获取动画实例,让图片开始执行动画效果

 if (imageitemdata != null && imageitemdata.size() > position) {
 // 正常显示
 // 判断是否需要显示删除按钮 ,为true则显示,并执行动画效果
 if (getclearimgshow()) {
 holder.imgclear.setvisibility(view.visible);
 customrotateanim anim = customrotateanim.getcustomrotateanim();
 anim.setduration(300);
 anim.setrepeatcount(2);
 anim.setinterpolator(new linearinterpolator()); // 设置为匀速
 holder.img.startanimation(anim);
 } else {
 // 关闭动画,隐藏删除按钮
 holder.img.clearanimation();
 holder.imgclear.setvisibility(view.gone);
 }
 holder.img.setimagebitmap(photobitmaputil.getcompressphoto(imageitemdata.get(position)));
 } else {
 ......省略......
 }

3.如何设置当图片达到最大数时,隐藏加号按钮

在使用gridadapter的时候,调用方需要传入一个最大图片数:

gridadapter = new gridadapter(mainactivity.this, 8);
mgridview.setadapter(gridadapter);

然后在gridadapter中接收这个最大图片数,并在getview()方法中对加号图片的显示进行管控

 if (imageitemdata != null && imageitemdata.size() > position) {
 // 显示选择的图片
 ......省略......
 } else {
 // 显示加号按钮
 // 图片数达到最大限制时隐藏加号图片
 if (imageitemdata.size() != imagesum) {
 holder.imgclear.setvisibility(view.gone); // 不显示删除按钮
 holder.img.clearanimation(); // 去除动画
 holder.img.setimagebitmap(maddbitmap);
 }
 }

“gridadapter.getcount() - 1”是因为我们在添加加号图片时加了1,所以使用时需要减1

 // 点击图片
 mgridview.setonitemclicklistener(new adapterview.onitemclicklistener() {
 @override
 public void onitemclick(adapterview<?> parent, view view, int position, long id) {
 // 如果单击时删除按钮处在显示状态,则隐藏它
 if (gridadapter.getclearimgshow()) {
  gridadapter.setclearimgshow(false);
  gridadapter.notifydatasetchanged();
 } else {
  if (gridadapter.getcount() - 1 == position) {
  // 判断是否达到了可添加图片最大数
  if (!(gridadapter.imageitemdata.size() == gridadapter.imagesum)) {
  selectphoto.showpopupselect(mgridview);
  }
  } else {
  popupviewgridphoto(position);
  }
 }

 }
 });

4.如何降低图片加载时的内存消耗量

要在gridview中显示那么多的图片,肯定是需要多图片进行压缩处理的,不然很容易出现oom错误
这里通过质量压缩,降低加载图片的内存大小

 /**
 * 把原图按1/5的比例压缩
 *
 * @param path 原图的路径
 * @return 压缩后的图片
 */
 public static bitmap getcompressphoto(string path) {
 bitmapfactory.options options = new bitmapfactory.options();
 options.injustdecodebounds = false;
 options.insamplesize = 5; // 图片的长宽设置为原来的五分之一
 bitmap bmp = bitmapfactory.decodefile(path, options);
 options = null;
 return bmp;
 }

也可以通过其它的方式,可以参考这篇博客《android避免内存溢出(out of memory)方法总结》

5.如何防止部分手机拍照后图片被旋转的问题

在测试中,部分三星手机拍摄完照片后会把图片旋转90度,这个设计实在是坑,为此还得专门为了这个问题进行处理,每次拍摄完照片后都要获取图片的旋转角度,如果图片被旋转了的话就再旋转回去
可以参考这篇博客
《android 解决部分手机拍照后获取的图片被旋转的问题》

6.如何让图片左右摇摆

想要实现图片左右摇摆的效果,需要我们自定义animation
可参看这篇博客
《android 自定义animation实现view摇摆效果》

这里就先介绍这么多,详细的解释代码注释中都有的,就不再多说啦

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。