全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

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

 

而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摇摆效果》

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

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


# Android自定义组件获取本地图片  # Android获取本地图片  # Android获取相机拍照图片  # Android组件Glide实现图片平滑滚动效果  # Android中ViewPager组件的基本用法及实现图片切换的示例  # android Gallery组件实现的iPhone图片滑动效果实例  # Jetpack Compose图片组件使用实例详细讲解  # 这篇  # 设置为  # 判断是否  # 找了  # 加载  # 自定义  # 时就  # 中对  # 单击  # 博客  # 左右摇摆  # 是因为  # 手机拍照  # 都要  # 就能  # 还会  # 这么多  # 那么多  # 中有  # 很久 


相关文章: 浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?  宿州网站制作公司兴策,安徽省低保查询网站?  css网站制作参考文献有哪些,易聊怎么注册?  图册素材网站设计制作软件,图册的导出方式有几种?  如何快速打造个性化非模板自助建站?  如何通过云梦建站系统实现SEO快速优化?  建站主机选购指南与交易推荐:核心配置解析  免费制作小说封面的网站有哪些,怎么接网站批量的封面单?  学校建站服务器如何选型才能满足性能需求?  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  网站网页制作专业公司,怎样制作自己的网页?  制作电商网页,电商供应链怎么做?  如何配置WinSCP新建站点的密钥验证步骤?  网站企业制作流程,用什么语言做企业网站比较好?  宁波自助建站系统如何快速打造专业企业网站?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  C++如何使用std::optional?(处理可选值)  如何通过山东自助建站平台快速注册域名?  行程制作网站有哪些,第三方机票电子行程单怎么开?  建站之星伪静态规则如何设置?  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  制作网站的软件免费下载,免费制作app哪个平台好?  建站168自助建站系统:快速模板定制与SEO优化指南  如何选择高效响应式自助建站源码系统?  如何在香港服务器上快速搭建免备案网站?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  如何选择高效便捷的WAP商城建站系统?  教学网站制作软件,学习*后期制作的网站有哪些?  c# 服务器GC和工作站GC的区别和设置  建站主机CVM配置优化、SEO策略与性能提升指南  网站制作知乎推荐,想做自己的网站用什么工具比较好?  在线教育网站制作平台,山西立德教育官网?  想学网站制作怎么学,建立一个网站要花费多少?  实例解析angularjs的filter过滤器  网站设计制作企业有哪些,抖音官网主页怎么设置?  如何在景安云服务器上绑定域名并配置虚拟主机?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  建站主机系统SEO优化与智能配置核心关键词操作指南  如何选择可靠的免备案建站服务器?  如何快速重置建站主机并恢复默认配置?  C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)  唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  黑客如何通过漏洞一步步攻陷网站服务器?  如何在七牛云存储上搭建网站并设置自定义域名?  网站制作需要会哪些技术,建立一个网站要花费多少?  金*站制作公司有哪些,金华教育集团官网?  如何高效搭建专业期货交易平台网站?  Swift中switch语句区间和元组模式匹配  已有域名和空间如何快速搭建网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。