Android史上最强的图片选择器-GalleryFinal

jopen 8年前

首先非常感谢对GalleryFinal提出意见和想法的童鞋们,使得GalleryFinal经过重重迭代变得完善起来。

GitHub地址 [Demo APK下载]()

简述

GalleryFinal是一个图片选择(单选/多选)、拍照、编辑、裁剪及旋转为一身的图片选择器。使用方便,功能可自己配置,GalleryFinal还可以根据开发者的喜好来选择主题,当然也支持自定义主题。而且GalleryFinal自身并没有强制绑定某个ImageLoader,开发者可以根据自己项目给GalleryFinal配置图片加载器。GalleryFinal还放弃了startActivityForResult+onActivityResult来获取选择结果,而是采用事件回调的机制。(我觉得startActivityForResult+onActivityResult太麻烦了,同意的点个赞吧,呵呵~)。GalleryFinal经过三四个月的版本迭代,修复bug,优化需求,已经处于稳定的状态。

也许有人会问:系统不是有相册选择器吗,为什么还有做一个GalleryFinal呢,有必要吗?我告诉你很有必要。微信,QQ等等app它们都是自己带图片选择器,并没有直接调系统的图片选择器。为什么要这么做呢?我总结出一下几点:

  • 最大的问题就是兼容性了,手机厂商那么多,相册软件那么多从而引起各种奇葩的问题

  • 有些手机拍照图片倒立情况(如三星和魅族)

  • 拿到的bitmap或uri为空

  • 非常频繁出现OOM

  • 不支持多选

  • 拍照/选择图片/裁剪视乎用起来有些麻烦,加上处理一些旋转、裁剪、压缩就更加麻烦了,代码多得不行不行的。

  • 系统的图片选择UI上与自己APP样式不统一

  • 有些不支持图片旋转

  • ....

使用GalleryFinal以上问题你都不用考虑,就是这么的任性。:joy:

虽然现在Github图片选择有很多,比如lovetuzitong的 MultiImageSelector ,habzy的 GridImagePicker ,还有就是YancyYe的 ImageSelectorImageSelector 似乎是在 GalleryFinal 1.0版本基础上做的改版)但是GalleryFinal有自己独特的优势:

  • 长期维护及时修复bug

  • 虚心采纳好的意见和想法

  • 功能强大/UI美观/可配置性强

  • ……

如何使用

使用GalleryFinal只需要简单的几步:(这里只说AS使用方法,如果你还停留在eclipse时代请clone源码或下载最新的 aar 文件)

1、引入GalleryFinal

在build.gradle中添加以下语句:

compile 'cn.finalteam:galleryfinal:1.4.3'  compile 'com.android.support:support-v4:23.1.1'

2、配置通用功能/主题/ImageLoader

这里只做基础的讲解,需要更详细的文档可见 github

在你的Application中添加配置GallerFinal

//配置主题  //ThemeConfig.CYAN  ThemeConfig theme = new ThemeConfig.Builder()          ...          .build();  //配置功能  FunctionConfig functionConfig = new FunctionConfig.Builder()          .setEnableCamera(true)          .setEnableEdit(true)          .setEnableCrop(true)          .setEnableRotate(true)          .setCropSquare(true)          .setEnablePreview(true)          ...          .build();    //配置imageloader  ImageLoader imageloader = new UILImageLoader();        //设置核心配置信息   CoreConfig coreConfig = new CoreConfig.Builder(context, imageloader, theme)          .setDebug(BuildConfig.DEBUG)          .setFunctionConfig(functionConfig)          ...          .build();  GalleryFinal.init(coreConfig);

GalleryFinal默认主题为DEFAULT(深蓝色),还自带主题:DARK(黑色主题)、CYAN(蓝绿主题)、ORANGE(橙色主题)、GREEN(绿色主题)和TEAL(青绿色主题),当然也支持自定义主题(Custom Theme),在自定义主题中用户可以配置字体颜色、图标颜色、更换图标、和背景色

  • 主题配置类说明

setTitleBarTextColor//标题栏文本字体颜色  setTitleBarBgColor//标题栏背景颜色  setTitleBarIconColor//标题栏icon颜色,如果设置了标题栏icon,设置setTitleBarIconColor将无效  setCheckNornalColor//选择框未选颜色  setCheckSelectedColor//选择框选中颜色  setCropControlColor//设置裁剪控制点和裁剪框颜色  setFabNornalColor//设置Floating按钮Nornal状态颜色  setFabPressedColor//设置Floating按钮Pressed状态颜色    setIconBack//设置返回按钮icon  setIconCamera//设置相机icon  setIconCrop//设置裁剪icon  setIconRotate//设置选择icon  setIconClear//设置清楚选择按钮icon(标题栏清除选择按钮)  setIconFolderArrow//设置标题栏文件夹下拉arrow图标  setIconDelete//设置多选编辑页删除按钮icon  setIconCheck//设置checkbox和文件夹已选icon  setIconFab//设置Floating按钮icon  setEditPhotoBgTexture//设置图片编辑页面图片margin外背景  setIconPreview设置预览按钮icon  setPreviewBg设置预览页背景
  • 功能配置类说明

setMutiSelect(boolean)//配置是否多选  setMutiSelectMaxSize(int maxSize)//配置多选数量  setEnableEdit(boolean)//开启编辑功能  setEnableCrop(boolean)//开启裁剪功能  setEnableRotate(boolean)//开启选择功能  setEnableCamera(boolean)//开启相机功能  setCropWidth(int width)//裁剪宽度  setCropHeight(int height)//裁剪高度  setCropSquare(boolean)//裁剪正方形  setSelected(List)//添加已选列表,只是在列表中默认呗选中不会过滤图片  setFilter(List list)//添加图片过滤,也就是不在GalleryFinal中显示  takePhotoFolter(File file)//配置拍照保存目录,不做配置的话默认是/sdcard/DCIM/GalleryFinal/  setRotateReplaceSource(boolean)//配置选择图片时是否替换原始图片,默认不替换  setCropReplaceSource(boolean)//配置裁剪图片时是否替换原始图片,默认不替换  setForceCrop(boolean)//启动强制裁剪功能,一进入编辑页面就开启图片裁剪,不需要用户手动点击裁剪,此功能只针对单选操作  setForceCropEdit(boolean)//在开启强制裁剪功能时是否可以对图片进行编辑(也就是是否显示旋转图标和拍照图标)  setEnablePreview(boolean)//是否开启预览功能
  • 图片加载器

开发者可以根据app现使用的ImageLoader来实现GalleryFinal ImageLoader,个人相对比较看好Glide,当然Fresco非常棒,不过它非常大。Picasso和UIL是老牌的ImageLoader也可以。至于Xutil3现在还不稳定,有些问题待修复。如果你有其他的ImageLoader也可以参考demo自行实现,如果有不明白之处加Q群(218801658)提问。

eg.

  • Glide

public class GlideImageLoader implements cn.finalteam.galleryfinal.ImageLoader {        @Override      public void displayImage(Activity activity, String path, final GFImageView imageView, Drawable defaultDrawable, int width, int height) {          Glide.with(activity)                  .load("file://" + path)                  .placeholder(defaultDrawable)                  .error(defaultDrawable)                  .override(width, height)                  .diskCacheStrategy(DiskCacheStrategy.NONE) //不缓存到SD卡                  .skipMemoryCache(true)                  //.centerCrop()                  .into(new ImageViewTarget<GlideDrawable>(imageView) {                      @Override                      protected void setResource(GlideDrawable resource) {                          imageView.setImageDrawable(resource);                      }                        @Override                      public void setRequest(Request request) {                          imageView.setTag(R.id.adapter_item_tag_key,request);                      }                        @Override                      public Request getRequest() {                          return (Request) imageView.getTag(R.id.adapter_item_tag_key);                      }                  });      }        @Override      public void clearMemoryCache() {      }  }

3、启动GalleryFinal

  • 单选打开相册

GalleryFinal.openGallerySingle(REQUEST_CODE_GALLERY, mOnHanlderResultCallback);  //带配置  GalleryFinal.openGallerySingle(REQUEST_CODE_GALLERY, functionConfig, mOnHanlderResultCallback);
  • 多选打开相册

GalleryFinal.openGalleryMuti(REQUEST_CODE_GALLERY, mOnHanlderResultCallback);  //带配置  FunctionConfig config = new FunctionConfig.Builder(MainActivity.this)      .setMutiSelectMaxSize(8)      .build();  GalleryFinal.openGalleryMuti(REQUEST_CODE_GALLERY, functionConfig, mOnHanlderResultCallback);
  • 拍照

GalleryFinal.openCamera(REQUEST_CODE_CAMERA, mOnHanlderResultCallback);  //带配置  GalleryFinal.openCamera(REQUEST_CODE_CAMERA, functionConfig, mOnHanlderResultCallback);
  • 裁剪

GalleryFinal.openCrop(REQUEST_CODE_CAMERA, mOnHanlderResultCallback);  //带配置  GalleryFinal.openCrop(REQUEST_CODE_CAMERA, functionConfig, mOnHanlderResultCallback);
  • 图片编辑

GalleryFinal.openEdit(REQUEST_CODE_CAMERA, mOnHanlderResultCallback);  //带配置  GalleryFinal.openEdit(REQUEST_CODE_CAMERA, functionConfig, mOnHanlderResultCallback);

技术原理

获取图片

通过内容提供者(Content Provider)获取到所有的图片信息,然后根据文件夹名称分类

图片加载

GalleryFinal通过ImageLoader接口对图片进行加载,图片质量,清晰度开发者自行决择。demo提供了UIL/Glide/Picsso/Fresco/xUtils3等框架的默认GalleryFinal ImageLoader实现

public interface ImageLoader{      void displayImage(Activity activity, String path, GFImageView imageView, Drawable defaultDrawable, int width, int height);      void clearMemoryCache();  }

其他

图片裁剪采用 android-crop

图片缩放采用 PhotoView

</div>

来自: http://segmentfault.com/a/1190000004263541