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

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

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

时间: 2024-08-26 04:24:07

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

Android中通过访问本地相册或者相机设置用户头像实例

目前几乎所有的APP在用户注册时都会有设置头像的需求,大致分为三种情况: (1)通过获取本地相册的图片,经过裁剪后作为头像. (2)通过启动手机相机,现拍图片然后裁剪作为头像. (3)在APP中添加一些自带的头像资源,供用户选择(不够人性化,目前很少使用). 这次我们简单介绍下通过获取本地相册以及相机拍摄的方法设置头像,实现思路如下: (1)通过startActivityForResult方法,分别传递调用系统相册的Intent和调用相机拍照的Intent来做选择 (2)调用Android系统中

android自定义组件实现方法_Android

本文实例讲述了android自定义组件实现方法.分享给大家供大家参考.具体如下: atts.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="TopBar"> <attr name="titleText" format="string"/> <

Android 自定义组件成JAR包的实现方法_Android

Android 自定义组件成JAR包的实现方法,这里对自己实现的Android View 组件进行JAR 包的处理.             在项目开发过程中,我们难免会用到自己去制作自定义的VIEW控件,之后我们别的项目如果需要的话就直接将其复制到对应的项目中使用,虽说这么做是一个解决问题的方法,但毕竟不是很好. 原因是,当我们项目积累越来越多,会发现自定义的控件越来越多,而且这些自定义的控件都是可以重复利用的,这时我们可以想想,如果把这些自定义控件都封装成一个JAR包,然后用一个项目积累起来

android自定义组件实现方法

本文实例讲述了android自定义组件实现方法.分享给大家供大家参考.具体如下: atts.xml: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="TopBar"> <attr name="titleText" format="string"/> <

Android自定义组件ListPopWindow_Android

先看一下效果: 效果就是这样,看一下实现,其实也没多难,就是想开源出来供小伙伴们使用,如有不合理地方,希望大家多多指正. 1.自定义PopWindow 首先我们分析一下,这样的效果肯定是一个PopWindow嵌套着listview,而上面的title.和下面的cancel是两个文本框,实现起来也比较简单. 然后我们在PopWindow中声明两个接口,用来回调cancel和item的点击事件 public interface OnPopItemClickListener{ void onPopIt

Android 自定义组件卫星菜单的实现

卫星菜单 ArcMenu 相信大家接触安卓,从新手到入门的过渡,就应该会了解到卫星菜单.抽屉.Xutils.Coolmenu.一些大神封装好的一些组件.这些组件在 Github 上面很容易搜得到,但是有时候打开会发现看不懂里面的代码,包括一些方法和函数 ..... 首先先上效果图: 实现效果 首先如果要想自定义组件 1.那么第一件事就是赋予自定义组件的属性,从效果图上看出,该组件可以存在屏幕的各个角落点,那么位置是其属性之一. 2.既然是卫星菜单,那么主按钮和其附属的小按钮之间的围绕半径也应该作

android自定义组件的简易实现

写这篇博客是为了复习之前在慕课上面有幸看到的自定义组件的实现,原理很简单,有三个步骤, 为自定义的组件做好声明:封装成具体的可以使用的组件类,并利用接口回调机制为其注册监听函数:想使用正常的组件的方式稍加修改后进行使用.是不是感觉思路很清晰啊,那么让我们一起来实现它吧. 1.做好声明,在新建的工程的value文件夹下创建一个名为atts.xml的文件,然后添加进自己将会使用到的"元素",需要注意的是declare-styleable 下的name属性,这个值尤其重要,这个和就是今后我们

android图像绘制--获取本地图片或拍照图片代码

从SD卡中获取图片资源,或者拍一张新的图片. 注释:拍照获取的话,可以指定图片的保存地址,在此不说明. 从SD卡中获取图片资源,或者拍一张新的图片. 先贴代码 获取图片: 注释:拍照获取的话,可以指定图片的保存地址,在此不说明.  代码如下 复制代码 CharSequence[] items = {"相册", "相机"}: new AlertDialog.Builder(this) .setTitle("选择图片来源") .setItems(it

Android自定义view实现圆形、圆角和椭圆图片(BitmapShader图形渲染)_Android

一.前言 Android实现圆角矩形,圆形或者椭圆等图形,一般主要是个自定义View加上使用Xfermode实现的.实现圆角图片的方法其实不少,常见的就是利用Xfermode,Shader.本文直接继承ImageView,使用BitmapShader方法来实现圆形.圆角和椭圆的绘制,等大家看我本文的方法后,其他的类似形状也就都能举一反三来来画出来了. 二.效果图: 三.BitmapShader简介 BitmapShader是Shader的子类,可以通过Paint.setShader(Shader