写在前面
实际开发经常会遇到读取相册或者拍照功能,网上也很非常多图库框架,都各有风格,也因此与自己的项目格格不入。再者,框架API太多,需要的配置太多,还要吃力研究。所以,本人摸索大多图库框架,提炼核心,写一个只提供核心的辅助类,剩下的就可以自行玩耍。
实现步骤
第一步,创建辅助类,使用弱引用持有Activity,防止内存溢出。
public class GalleryHelper{ private Activity mActivity; public GalleryHelper(Activity activity) { mActivity = new WeakReference<>(activity).get(); } }
第二步,创建文件夹实体类,代表文件夹数据。paths集合是文件夹下的所有路径。
public final class FolderEntity { private int num; private String name; private List<String> paths = new ArrayList<>(); public int getNum() { return paths.size(); } public List<String> getPaths() { return paths; } public void setName(String name) { this.name = name; } }
第三步,首先获取手机所有的图片,在Activity里有getLoaderManager方法获取一个LoaderManager实例,该类用于异步加载手机内数据监测,这里不做多分析。我们调用它的initLoader方法,前两个参数这里不需要,只要实现LoaderCallbacks接口,并且指定Cursor类型。LoaderCallbacks接口有三个覆盖方法,我们需要用到的是onCreateLoader方法和onLoadFinished方法,前者是初始化Loader,后者是加载完成后的回调。
mActivity.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { } @Override public void onLoaderReset(Loader<Cursor> loader) { } });
在onCreateLoader方法里,初始化CursorLoader,参数跟Cursor类下的query一样,第一个参数指定外部村粗多媒体URI;第二个参数是查找结果字段,这里只要了路径;第三个参数和第四个参数是搜索条件,条件为搜索jpeg格式和png格式,最后一个是按时间倒序搜索。
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { return new CursorLoader(mActivity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media.DATA}, MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?", new String[]{"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_ADDED + " DESC"); }
CursorLoader初始化完成之后,搜索的结果会回调在onLoadFinished方法。这时就可以处理搜索出来的图片路径。因为图片路径是没有分类,这里采用HashMap分类,以文件夹路径为key,具体文件夹FolderEntity类为value,如果当前图片路径的文件夹不存在则创建FolderEntity并且放入HashMap,存在则获取FolderEntity。
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { HashMap<String, FolderEntity> folderEntityHashMap = new HashMap<String, FolderEntity>(); if (cursor != null) { while (cursor.moveToNext()) { //图片路径 String path = cursor.getString( cursor.getColumnIndex(MediaStore.Images.Media.DATA)); // 路径不存在或者文件不存在就跳过 File file = new File(path); if (TextUtils.isEmpty(path) || !file.exists()) { continue; } String folerPath = file.getParent(); FolderEntity folderEntity; if (folderEntityHashMap.containsKey(folerPath)) { folderEntity = folderEntityHashMap.get(folerPath); } else { folderEntity = new FolderEntity(); folderEntityHashMap.put(file.getParentFile().getName(), folderEntity); } folderEntity.getPaths().add(path); } cursor.close(); } }
但是数据是要提供给外部的,HashMap就显得很麻烦,所以要转换ArrayList,并且按数量大小进行顺序。
private ArrayList<FolderEntity> map2List(HashMap<String, FolderEntity> mediaBeanMap) { Iterator<FolderEntity> iterator = mediaBeanMap.values().iterator(); ArrayList<FolderEntity> list = new ArrayList<FolderEntity>(); while (iterator.hasNext()) { list.add(iterator.next()); } Collections.sort(list, new Comparator<FolderEntity>() { @Override public int compare(FolderEntity lhs, FolderEntity rhs) { return lhs.getNum() > rhs.getNum() ? 1 : -1; } }); return list; }
使用接口将数据提供给外部。
public interface GalleryCallback { void complete(List<FolderEntity> list); } callback.complete(map2List(folderEntityHashMap));
第四步是实现拍照功能,这里实现是创建文件再启动拍照功能。
File imageStoreDir = new File(Environment.getExternalStorageDirectory(), "/DCIM/" + mActivity.getResources().getString(R.string.app_name)); if (!imageStoreDir.exists()) { imageStoreDir.mkdir(); } Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (captureIntent.resolveActivity(mActivity.getPackageManager()) != null) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA); String filename = String.format("IMG%s", dateFormat.format(new Date())); imagePath = new File(imageStoreDir, filename).getAbsolutePath(); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(imagePath))); mActivity.startActivityForResult(new Intent( MediaStore.ACTION_IMAGE_CAPTURE), REQUEST_CODE); }
定义回调接口,接收Activit的onActivityResult方法,表示回调成功把上面创建好的文件路径提供外部。
public interface CameraCallback { void complete(String path); } public void onActivityResult(int requestCode, int resultCode) { if (Activity.RESULT_OK == resultCode && REQUEST_CODE == requestCode) { if (cameraCallback != null) { cameraCallback.complete(imagePath); } } }
外部调用
galleryHelper = new GalleryHelper(this); galleryHelper.loadImages(new GalleryHelper.GalleryCallback() { @Override public void complete(List<FolderEntity> list) { //加载本地图片返回结果 } }); findViewById(R.id.btn_camera).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { galleryHelper.openCamera(new GalleryHelper.CameraCallback() { @Override public void complete(String path) { //拍照返回结果 } }); } }); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //使用拍照,必须接收Activity的onActivityResult方法 galleryHelper.onActivityResult(requestCode, resultCode); }
别忘了加权限,这里为了简单实现,我把targetSdkVersion设置23以下,23和23以上的需要自行加上动态权限。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
整体就完成了,使用非常方便,有了这图库辅助器就可以自定义风格,再也不用受约束。网上大多开源图片选择器的搜索图片都是如此,但这例子难免有bug,不足之处望指教。
github地址:https://github.com/tanxinye/GalleryHelper
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍简单实现android轮播图,包括了简单实现android轮播图的使用技巧和注意事项,需要的朋友参考一下 轮播图是很常用的一个效果 核心功能已经实现 没有什么特殊需求 自己没事研究的 所以封装的不太好 一些地方还比较糙 为想要研究轮播图的同学提供个参考 目前测试图片为mipmap中的图片 没有写从网络加载图片 可自行根据需求在getShowView()方法中修改 1.定时切换 通过h
本文向大家介绍简单实现Android绘图板,包括了简单实现Android绘图板的使用技巧和注意事项,需要的朋友参考一下 本文这个实例通过前面学过的Paint、Canvas等2D绘画技术来实现一个简单的Android的绘图板。 具体实现代码: 创建一个名为DrawView的类,该类继承自android.view.View类。在该类中,首先定义程序中所需的属性,然后添加构造方法,并重写onDraw(C
本文向大家介绍Android简单实现画图功能,包括了Android简单实现画图功能的使用技巧和注意事项,需要的朋友参考一下 如何在图片上画画呢?这里写了一个demo,供大家参考 一、先看一眼工程结构 工程结构: 二、自定义view 这个自定义view实现了保留轨迹的功能,代码如下 三、主页面布局文件 主页面布局文件 四、主Activity代码 五、效果 运行效果图如下 六、疑问 当线条变粗时,线条
本文向大家介绍Android实现简单画图画板,包括了Android实现简单画图画板的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android实现简单画图画板的具体代码,供大家参考,具体内容如下 效果如图: 布局文件: MainActivity.java 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍python实现连连看辅助(图像识别),包括了python实现连连看辅助(图像识别)的使用技巧和注意事项,需要的朋友参考一下 个人兴趣,用python实现连连看的辅助程序,总结实现过程及知识点。 总体思路 1、获取连连看程序的窗口并前置 2、游戏界面截图,将每个一小图标切图,并形成由小图标组成的二维列表 3、对图片的二维列表遍历,将二维列表转换成由数字组成的二维数组,图片相同的数值相
本文向大家介绍Android辅助功能AccessibilityService与抢红包辅助,包括了Android辅助功能AccessibilityService与抢红包辅助的使用技巧和注意事项,需要的朋友参考一下 推荐阅读:Android中微信抢红包插件原理解析及开发思路 抢红包的原理都差不多,一般是用Android的辅助功能(AccessibilityService类)先监听通知栏事件或窗口变化事