作者:简 | 来源:互联网 | 2023-10-10 14:21
1.简介PhotoPicker,是一款开源的图片选择器。效果上和微信相似。2.使用方法2.1添加依赖dependencies{compileme.iwf.photopicker:
1. 简介
PhotoPicker, 是一款开源的图片选择器。效果上和微信相似。
2. 使用方法
2.1 添加依赖
dependencies {
compile 'me.iwf.photopicker:PhotoPicker:0.9.5@aar'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
}
- appcompat-v7version >= 23.0.0
或者使用download源码,然后使用module依赖,我平时使用是这种方式。
dependencies {
...
compile project(':PhotoPicker')
...
}
2.2 代码集成
如下内容来自Github介绍
PhotoPicker.builder()
.setPhotoCount(9)
.setShowCamera(true)
.setShowGif(true)
.setPreviewEnabled(false)
.start(this, PhotoPicker.REQUEST_CODE)
ArrayList photoPaths = ...;
PhotoPreview.builder()
.setPhotos(selectedPhotos)
.setCurrentItem(position)
.setShowDeleteButton(false)
.start(MainActivity.this);
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == PhotoPicker.REQUEST_CODE) {
if (data != null) {
ArrayList photos =
data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
}
}
}
"http://schemas.android.com/apk/res/android"
>
"android.permission.READ_EXTERNAL_STORAGE"/>
"android.permission.WRITE_EXTERNAL_STORAGE"/>
"android.permission.CAMERA" />
...
>
...
"me.iwf.photopicker.PhotoPickerActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
/>
"me.iwf.photopicker.PhotoPagerActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"/>
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# nineoldandroids
-keep interface com.nineoldandroids.view.** { *; }
-dontwarn com.nineoldandroids.**
-keep class com.nineoldandroids.** { *; }
# support-v7-appcompat
-keep public class android.support.v7.widget.** { *; }
-keep public class android.support.v7.internal.widget.** { *; }
-keep public class android.support.v7.internal.view.menu.** { *; }
-keep public class * extends android.support.v4.view.ActionProvider {
public (android.content.Context);
}
# support-design
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
3. 源码分析
3.1 代码结构
类名 |
描述 |
PhotoPicker |
内部类PhotoPickerBuilder是关键,设置图片选择参数,启动PhotoPickerActivity均在此 |
PhotoPickerActivity |
图片选择界面,两个Fragment:PhotoPickerFragment,ImagePagerFragment,一个用来图片选择,一个用来预览图片 |
PhotoPagerActivity |
图片预览界面,和PhotoPickerActivity使用同样的布局文件,但是只有一个Fragment,ImagePagerFragment |
PhotoPreview |
内部类PhotoPreviewBuilder是关键,设置预览参数,启动PhotoPagerActivity均在此 |
PhotoPickerFragment |
图片选择Fragment,在PhotoPickerActivity中使用到,Toolbar + RecyclerView + ListPopupWindow |
ImagePagerFragment |
图片预览Framgment,在PhotoPickerActivity中如果支持预览,点击图片后就会切换到此Fragment,单独使用PhotoPreview自然也是用的ImagePagerFragment |
ImageCaptureManager |
拍照管理类,当PhotoPicker中setShowCamera设为true后,点击拍照项,会调用系统相机拍照,相关方法实现均在ImageCaptureManager |
PhotoGridAdapter |
图片选择界面RecyclerView的 Adapter,瀑布流,主要因为它继承SelectableAdapter,平时开发有相同需求可以借鉴一些这个实现 |
PopupDirectoryListAdapter |
底部图片分类文件夹ListPopupWindow的Adapter |
MediaStoreHelper |
图片数据查找Helper类,单独拿出来看,Loader的使用 |
SelectableAdapter |
自定义用于选择的RecyclerView.Adapter,支持toggleSelection |
Selectable |
Selectable接口,支持toggleSelection |
PhotoPagerAdapter |
ImagePagerFragment中用于预览的ViewPager的Adapter |
PhotoDirectory |
图片目录对象,在PopupDirectoryListAdapter中使用到 |
Photo |
图片对象,存放id和Path,分别对应数据库中图片_ID字段和DATA字段 |
OnItemCheckListener |
图片选择框的点击事件接口 |
OnPhotoClickListener |
图片点击事件接口,应该只有在图片选择器支持预览的情况下使用 |
AndroidLifecycleUtils |
判断是否可以加载图片 |
FileUtils |
文件处理工具类,只有一个判断文件是否存在的方法 |
PermissionsConstant |
关于权限请求的部分常量 |
PermissionsUtils |
权限请求工具类 |
PhotoDirectoryLoader |
继承CursorLoader,从数据库中读取数据 |
SquareItemLayout |
图片选择器Item布局 |
TouchImageView |
预览图片自定义元件 |
3.2 源码设计思路
从代码结构和使用方法上来看,PhotoPicker是将图片选择作为一个单独的功能模块解耦出来,以Activity的形式进行PhotoPicker或者是PhotoPreview,在合适的位置创建Intent显示启动PhotoPagerAcitivty(预览)或者是PhotoPickerActivity(选择图片)。针对图片选择的场景,通过onActivityResult得到所选图片的Path。
方法 |
参数 |
描述 |
setPhotoCount(int photoCount) |
EXTRA_MAX_COUNT(“MAX_COUNT”) |
设置可选的最大图片数量 |
setShowCamera(boolean showCamera) |
EXTRA_SHOW_CAMERA(“SHOW_CAMERA”) |
是否显示拍照 |
setShowGif(boolean showGif) |
EXTRA_SHOW_GIF(“SHOW_GIF”) |
是否显示gif图 |
setGridColumnCount(int columnCount) |
EXTRA_GRID_COLUMN(“column”) |
设置图片选择网格的列数 |
setSelected(ArrayList imagesUri) |
EXTRA_ORIGINAL_PHOTOS(“ORIGINAL_PHOTOS”) |
已选照片 |
setPreviewEnabled(boolean previewEnabled) |
EXTRA_PREVIEW_ENABLED(“PREVIEW_ENABLED”) |
图片网格视图中是否支持预览 |
参数 |
描述 |
KEY_SELECTED_PHOTOS(“SELECTED_PHOTOS”) |
所选图片Path 列表 |
方法 |
参数 |
描述 |
setCurrentItem(int currentItem) |
EXTRA_CURRENT_ITEM(“current_item”) |
设置预览界面当前显示图片序号 |
setPhotos(ArrayList photoPaths) |
EXTRA_PHOTOS(“photos”) |
设置预览图片列表,图片Path的ArrayList |
setShowDeleteButton(boolean showDeleteButton) |
EXTRA_SHOW_DELETE(“show_delete”) |
是否显示删除按钮 |
- Build设计模式
PhotoPicker和PhotoPreview都是采用的Build设计模式。利用构建者模式,可以清晰的管理参数,层次清晰,增加代码的可读性,Android源码系统中也有此模式的大量使用,如AlertDialog.Builder等等。
PhotoPickerBuilder和PhotoPreviewBuilder正式采用的这种设计模式。
- Loader机制
loader机制,包括LoaderManager,Loader,LoaderCallbacks三部分,
LoaderManager 来管理我们的laoder实例,获取来初始化,重启一个loader,
Loader 来执行我们的异步操作,有开始,完成,后台等接口实现
LoaderCallbacks 来执行我们的loader回调,主要是绑定分发Loader,完成加载,重置数据等
MediaStoreHelper中只有一个方法getPhotoDirs,方法中使用
activity.getSupportLoaderManager()
.initLoader(0, args,
new PhotoDirLoaderCallbacks(activity, resultCallback));
的方式初始化Loader,然后在
PhotoDirLoaderCallbacks实现
LoaderManager.LoaderCallbacks接口。onCreateLoader方法中创建PhotoDirectoryLoader并传入参数,onLoadFinished返回后台数据库查询结果。
4. 备注
PhotoPicker,可以满足日常开发需求,代码结构非常清晰,可以直接根据自己的需求在源码上进行定制修改。感谢大神的开源精神。
个人微信公众号:Learning_Of_ALL,欢迎大家扫码关注,Android技术交流。