<Android 开源库> 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'
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- appcompat-v7version >= 23.0.0
或者使用download源码,然后使用module依赖,我平时使用是这种方式。
dependencies {
...
compile project(':PhotoPicker')
...
}
- 1
- 2
- 3
- 4
- 5
2.2 代码集成
如下内容来自Github介绍
- Pick Photo
PhotoPicker.builder()
.setPhotoCount(9)
.setShowCamera(true)
.setShowGif(true)
.setPreviewEnabled(false)
.start(this, PhotoPicker.REQUEST_CODE);
- 1
- 2
- 3
- 4
- 5
- 6
- Preview Photo
ArrayList<String> photoPaths = ...;
PhotoPreview.builder()
.setPhotos(selectedPhotos)
.setCurrentItem(position)
.setShowDeleteButton(false)
.start(MainActivity.this);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- onActivityResult
@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<String> photos =
data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
>
<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" />
<application
...
>
...
<activity android:name="me.iwf.photopicker.PhotoPickerActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
/>
<activity android:name="me.iwf.photopicker.PhotoPagerActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"/>
</application>
</manifest>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- Custom Style
<style name="actionBarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="android:textColorPrimary">@android:color/primary_text_light</item>
<item name="actionBarSize">@dimen/actionBarSize</item>
</style>
<style name="customTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="actionBarTheme">@style/actionBarTheme</item>
<item name="colorPrimary">#FFA500</item>
<item name="actionBarSize">@dimen/actionBarSize</item>
<item name="colorPrimaryDark">#CCa500</item>
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- ProGuard
# 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 <init>(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$* { *; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
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。
- PhotoPicker
| 方法 | 参数 | 描述 |
|---|---|---|
| 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< String> imagesUri) | EXTRA_ORIGINAL_PHOTOS(“ORIGINAL_PHOTOS”) | 已选照片 |
| setPreviewEnabled(boolean previewEnabled) | EXTRA_PREVIEW_ENABLED(“PREVIEW_ENABLED”) | 图片网格视图中是否支持预览 |
| 参数 | 描述 |
|---|---|
| KEY_SELECTED_PHOTOS(“SELECTED_PHOTOS”) | 所选图片Path 列表 |
- PhotoPreview
| 方法 | 参数 | 描述 |
|---|---|---|
| setCurrentItem(int currentItem) | EXTRA_CURRENT_ITEM(“current_item”) | 设置预览界面当前显示图片序号 |
| setPhotos(ArrayList< String> 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< Cursor>接口。onCreateLoader方法中创建PhotoDirectoryLoader并传入参数,onLoadFinished返回后台数据库查询结果。
4. 备注
PhotoPicker,可以满足日常开发需求,代码结构非常清晰,可以直接根据自己的需求在源码上进行定制修改。感谢大神的开源精神。
<Android 开源库> PhotoPicker 从头到脚的更多相关文章
- PhotoPicker 从头到脚
1. 简介 PhotoPicker, 是一款开源的图片选择器.效果上和微信相似. 2. 使用方法 2.1 添加依赖 dependencies { compile 'me.iwf.photopicker ...
- 1.设计模式第一步-《设计模式从头到脚舔一遍-使用C#实现》
更新记录: 完成第一次编辑:2022年4月23日20:29:33. 加入小黄人歌曲:2022年4月23日21:45:36. 1.1 设计模式(Design Pattern)是什么 设计模式是理论.是前 ...
- mysql的从头到脚优化之数据库引擎的选择(转载)
一. Mysql常用的存储引擎包括Innodb和Myisam以及memory引擎,但是最常用的莫过于Innodb引擎和MyISAM引擎,下边分别做下记录和比较: 下面思考下这几个问题: 你的数据库需要 ...
- mysql的从头到脚优化之服务器参数的调优
一. 说到mysql的调优,有许多的点可以让我们去做,因此梳理下,一些调优的策略,今天只是总结下服务器参数的调优 其实说到,参数的调优,我的理解就是无非两点: 如果是Innodb的数据库,innod ...
- 并发编程(一):从头到脚解读synchronized
一.目录 1.多线程启动方式 2.synchronized的基本用法 3.深度解析synchronized 4.同步方法与非同步方法是否能同时调用? 5.同步锁是否可重入(可重入锁)? 6.异常是否会 ...
- Struts2从头到脚--学习笔记(自认为比较重要的)
一. Struts2框架介绍 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与 ...
- 【Android开源库】 PagerSlidingTabStrip从头到脚
简介 PagerSlidingTabStrip,是我个人经常使用到的一个和ViewPager配合的页面指示器,可以满足开发过程中常用的需求,如类似于今日头条的首页新闻内容导航栏等等,之前自己开发的Ju ...
- <Android 基础(三十四)> TabLayout 从头到脚
1. 简介 1.TabLayout给我们提供的是一排横向的标签页 2.#newTab()这个方法来创建新的标签页,然后用过#setText()和#setIcon方法分别修改标签页的文本和图标,创建完成 ...
- <Android开源库> PagerSlidingTabStrip从头到脚
简介 PagerSlidingTabStrip,是我个人经常使用到的一个和ViewPager配合的页面指示器,可以满足开发过程中常用的需求,如类似于今日头条的首页新闻内容导航栏等等,之前自己开发的Ju ...
随机推荐
- 码云创建maven工程
码云创建maven工程步骤 1.现在码云上创建工程2.拉取到本地3.使用"touch .gitignore"命令创建.gitignore文件4.在文件中添加过滤文件: .setti ...
- JavaScript Data.parse()转化时间戳安卓和ISO不兼容
Data.parse()获取时间戳,在Android是没有问题的,但是在ISO就不行了,原因在于转化成时间戳的时间格式不一样. Android的格式是如“2017-12-12 12:12:12”,IS ...
- mongodb2.X添加权限
1.连接mongodb数据库(如果mongo命令没有做环境变量配置,需要定位到有mongo命令的目录) root@AY140709212620347s22Z:~# mongo MongoDB shel ...
- DevOps之技能面
<教学手册(Teaching Manual)> 教学:人类培养态度.传授知识.训练技能的活动.教学目的:知识与技能的层次:(了解.理解.熟悉.掌握.精通).教学手段:理论与实践的方面:(科 ...
- Android aapt 工具介绍(转)
目录 AAPT 工具介绍 AAPT 的帮助信息 查看AAPT的版本 使用AAPT列出资源包apk文件列表 使用AAPT打包资源文件 使用AAPT解压资源包apk 来自:http://mmmyddd ...
- 如何将SQL Server 2000备份的数据库文件还原(升级)为SQL Server 2005或更高版本的数据库?
其实很简单,有两种方法. 方法一:将SQL Sever 2000数据库备份的数据库文件名后面加上“.bak”,然后直接在SQL Sever 2005或者高版本软件里面直接还原即可: 方法二:在SQL ...
- 错误: 未能完成程序集的安装(hr = 0x8007000b),.net程序关于使用Oracle.DataAccess.dll不同版本x86和x64问题,即oracle odp.net 32位/64位版本的问题
如果你的机器上安装了odp.net,且确信machine.config也有类似以下结节:(64位+.net 4.0环境下,machine.config可能会有4份,分别对应于.net2.0/4.0的3 ...
- 入坑Vue
长期的后端数据开发着实有些枯燥无趣,项目完工,闲暇之际,最近一直在研究前端方面的东西,不得感叹,前端技术发展速度快的让人有些目不暇接,从jQuery开启的插件化时代,几乎许多网站都被jQuery支配, ...
- Spine Skeleton Animation(2D骨骼动画)
骨骼动画 首先我们来看到底什么是骨骼动画: 在早期的机器上,渲染本身已经占用了很多CPU资源,因此,对于渲染,往往采取的是一种空间换时间的策略,以避免在模型的渲染中继续加重CPU的负担.帧动画模型在这 ...
- gnome-shell 使用 notify-send 发送桌面消息
什么是notify-send? notify-send - a program to send desktop notifications 怎么使用? NAME notify-send - a pro ...