Giter VIP home page Giter VIP logo

donkingliang / imageselector Goto Github PK

View Code? Open in Web Editor NEW
779.0 17.0 168.0 599 KB

Android图片选择器,仿微信的图片选择器的样式和效果。支持图片的单选、限数量的多选和不限数量的多选,支持图片剪切。支持图片预览和图片文件夹的切换。支持在选择图片时调用相机拍照,也支持不用打开相册直接调用相机拍照。

License: Apache License 2.0

Java 100.00%
imageselector imageselector-android android android-library canera

imageselector's Introduction

ImageSelector

Android图片选择器,仿微信的图片选择器的样式和效果。支持图片的单选、限数量的多选和不限数量的多选。支持图片预览和图片文件夹的切换。支持在选择图片时调用相机拍照,也支持不用打开相册直接调用相机拍照。

先上效果图:

相册 文件夹 预览

1、引入依赖

在Project的build.gradle在添加以下代码

	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

在Module的build.gradle在添加以下代码

	implementation 'com.github.donkingliang:ImageSelector:2.2.1'

从2.0.0版本开始,库迁移androidx。没有使用androidx的项目可以使用1.9.3版本。

2、配置AndroidManifest.xml

注意: 1.7.0版本后,不需要再配置FileProvider,ImageSelector内部已经配置了。

//储存卡的读写权限
<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" />

//图片选择Activity
<activity android:name="com.donkingliang.imageselector.ImageSelectorActivity"
	//去掉Activity的ActionBar。
	//使用者可以根据自己的项目去配置,不一定要这样写,只要让Activity的ActionBar去掉就可以了。
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    //横竖屏切换处理。
    //如果要支持横竖屏切换,一定要加上这句,否则在切换横竖屏的时候会发生异常。
    android:configChanges="orientation|keyboardHidden|screenSize"/>
    
//图片预览Activity
<activity android:name="com.donkingliang.imageselector.PreviewActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    android:configChanges="orientation|keyboardHidden|screenSize"/>

//图片剪切Activity
<activity
    android:name="com.donkingliang.imageselector.ClipImageActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar" />

<!-- Android 7.0 文件共享配置,1.7.0之前必须配置,1.7.0后不需要 -->
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

在res/xml文件夹下创建file_paths.xml文件(名字可以自己定义)

<?xml version="1.0" encoding="utf-8"?>
<paths>

    <!-- 这个是保存拍照图片的路径,必须配置。 -->
    <external-path
        name="images"
        path="Pictures" />
</paths>

3、调起图片选择器

ImageSelector支持图片的单选、限数量的多选和不限数量的多选。还可以设置是否使用相机、是否剪切图片等配置。ImageSelector提供了统一的调起相册的方法。

 //单选
 ImageSelector.builder()
     .useCamera(true) // 设置是否使用拍照
     .setSingle(true)  //设置是否单选
     .canPreview(true) //是否可以预览图片,默认为true
     .start(this, REQUEST_CODE); // 打开相册

//限数量的多选(比如最多9张)
ImageSelector.builder()
    .useCamera(true) // 设置是否使用拍照
    .setSingle(false)  //设置是否单选
    .setMaxSelectCount(9) // 图片的最大选择数量,小于等于0时,不限数量。
    .setSelected(selected) // 把已选的图片传入默认选中。
    .canPreview(true) //是否可以预览图片,默认为true
    .start(this, REQUEST_CODE); // 打开相册

//不限数量的多选
ImageSelector.builder()
    .useCamera(true) // 设置是否使用拍照
    .setSingle(false)  //设置是否单选
    .setMaxSelectCount(0) // 图片的最大选择数量,小于等于0时,不限数量。
    .setSelected(selected) // 把已选的图片传入默认选中。
    .canPreview(true) //是否可以预览图片,默认为true
    .start(this, REQUEST_CODE); // 打开相册

//单选并剪裁
ImageSelector.builder()
    .useCamera(true) // 设置是否使用拍照
    .setCrop(true)  // 设置是否使用图片剪切功能。
    .setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。
    .setSingle(true)  //设置是否单选
    .canPreview(true) //是否可以预览图片,默认为true
    .start(this, REQUEST_CODE); // 打开相册
       
//仅拍照
ImageSelector.builder()
    .onlyTakePhoto(true)  // 仅拍照,不打开相册
    .start(this, REQUEST_CODE);
    
//拍照并剪裁
ImageSelector.builder()
    .setCrop(true) // 设置是否使用图片剪切功能。
    .setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。
    .onlyTakePhoto(true)  // 仅拍照,不打开相册
    .start(this, REQUEST_CODE);
    

REQUEST_CODE就是调用者自己定义的启动Activity时的requestCode,这个相信大家都能明白。selected可以在再次打开选择器时,把原来已经选择过的图片传入,使这些图片默认为选中状态。

如果是仅拍照模式(onlyTakePhoto = true)时,useCamera无论设置什么,都是为true。

4、接收选择器返回的数据

在Activity的onActivityResult方法中接收选择器返回的数据。

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && data != null) {
	    //获取选择器返回的数据
            ArrayList<String> images = data.getStringArrayListExtra(
            ImageSelector.SELECT_RESULT);
	    
	    	/**
     		* 是否是来自于相机拍照的图片,
     		* 只有本次调用相机拍出来的照片,返回时才为true。
     		* 当为true时,图片返回的结果有且只有一张图片。
		*/
	    boolean isCameraImage = data.getBooleanExtra(ImageSelector.IS_CAMERA_IMAGE, false);
        }
    }

ImageSelector.SELECT_RESULT是接收数据的key。数据是以ArrayList的字符串数组返回的,就算是单选,返回的也是ArrayList数组,只不过这时候ArrayList只有一条数据而已。ArrayList里面的数据就是选中的图片的文件路径。

适配android 10

兼容android 10的手机请使用1.7.0版本。

由于android 10不允许应用直接访问外部文件,所以在android 10及以上的手机,ImageSelect返回的图片链接可能无法直接加载,因为ImageSelector返回的是图片在手机里的地址。但是可以通过uri进行加载,ImageSelector内部提供了一些方法可以供外部使用,用于适配android 10。

如何在Android 10加载手机本地图片,请看我的这篇博客

//是否是android 10及以上
VersionUtils.isAndroidQ();

// android 10可以通过图片uri加载手机本地图片。

//图片链接转uri
Uri uri = UriUtils.getImageContentUri(Context context, String path);

//通过uri加载图片
 Glide.with(mContext).load(uri).into(ivImage);
 ivImage.setImageURI(uri);
 // 或者
Bitmap bitmap = ImageUtil.getBitmapFromUri(Context context, Uri uri);

注意: 剪切返回的图片的图片链接是放在应用的私有目录的,所以剪切返回的图片可以直接用path加载,不需要转成uri再加载。ImageSelector提供了判断图片链接是否是剪切的图片的方法。

// 是否是剪切返回的图片
ImageUtil.isCutImage(mContext, path);

图片预加载和缓存

由于从手机中加载图库是个耗时操作,图片太多时,打开图库可能等待时间过长,用户体验不好。所以在2.1.0版本和1.9.0版本开始,提供了预加载手机图片并缓存的功能。你可以在用户打开图片选择器前,预先加载手机图片,这样在用户打开图片选择器时,会直接从缓存中读取图片列表,大大提升选择器的加载速度。

选择器默认不开启预加载并缓存功能,如果需要预加载,请调用下面的方法:

ImageSelector.preload(context);

调用这个方法的时机没有特殊的要求,只要是在打开选择器前调用就可以了。

注意: 由于加载手机图片需要申请WRITE_EXTERNAL_STORAGE权限,所以在调用该方法前,请确保权限已申请。

在选择器使用完毕,不再需要时,可以调用下面方法清空缓存:

ImageSelector.clearCache(context);

清空缓存的操作不是必须的,如果不清空,缓存会一直保留,直到app被回收。因为缓存的是图片的路径,所以不会占用太多的内存。

版本节点

这里记录的是重要的版本更新节点,全部的版本及更新内容请看这里

2.1.0版本&1.9.0版本

添加图片预加载和缓存功能。

2.0.0版本

迁移androidx。没有使用androidx的项目可以使用1.9.2版本。

1.8.0版本

1、添加直接打开相机拍照功能。

2、优化图片预览页,适配刘海屏。

1.7.0版本

1、适配android 10。

2、添加自定义FileProvider,从1.7.0开始,使用者不需要再配置FileProvider。

1.5.0版本

1、更新Glide版本到4.x。

2、修改targetSdkVersion为27。

ImageSelector从1.5.0版本开始使用了Glide 4.x的版本,由于Glide 3.x版本和4.x版本在使用上有所差异,如果你的项目使用了Glide 3.x版本,而又不想升级到4.x,那么你也可以使用ImageSelector:1.4.0版本,它和新的版本在使用和功能上都会有所差异。ImageSelector 1.4.0

想要了解ImageSelector的实现思路和核心代码的同学请看这里:Android 实现一个仿微信的图片选择器

imageselector's People

Contributors

donkingliang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imageselector's Issues

单独使用图片预览的问题

单独使用PreviewActivity页面,传递数据之后无法拿到更改过后(点击右下取消选择后)的数据,而且更改过后会抛异常(由vp数据源更改引起)

拍照点击确定就报错.系统是5以下的.5以上的没测试.logcat你看

12-09 17:18:35.455 431-441/? W/Binder: Caught a RuntimeException from the binder stub implementation.
java.lang.NullPointerException
at android.inputmethodservice.IInputMethodWrapper.setSessionEnabled(IInputMethodWrapper.java:280)
at com.android.internal.view.IInputMethod$Stub.onTransact(IInputMethod.java:129)
at android.os.Binder.execTransact(Binder.java:404)
at dalvik.system.NativeStart.run(Native Method)

ImageAdapter.getFirstVisibleImage()下标越界

com.donkingliang.imageselector.adapter.ImageAdapter.getFirstVisibleImage()
mImages.get(firstVisibleItem == 0 ? 0 : firstVisibleItem - 1);
firstVisibleItem小于0就报错了,过滤firstVisibleItem扩大些范围吧.
建议改为:mImages.get(firstVisibleItem <= 0 ? 0 : firstVisibleItem - 1);

你这个工具不适用于fragment

你可以自己试试,在Fragment里面是无法回调onActivityResult的,因为fragment回调onActivityResult只能直接使用startActivityforResult,参数那里只能传入getActivity

依赖的Glide版本太低

目前的框架支持4.5,但是4.9不支持;打开后会直接闪退;
作者什么时候考虑升级下Glide版本

图片列表不刷新

使用该图片选择器选择图片后进行编辑,再次选择时,图片并没有改动,而实际文件已经变动了,不知道这个问题如何解决。(关机重启后,图片则会更新,难道是缓存吗?)
关于这个问题,系统相册也是不改动,需要发送一个图片改动的广播可以解决。

选择圆形图标太小

最近在使用功能的时候发现选择的按钮有点小,点击选择不太方便,能不能把选择按钮放大一些。还有发现一个问题,单张选择的时候会报错。

关于图片预览BUG

与调起图片选择器中的预览按钮无关
描述:在图片选择器选择完图片后进行了列表展示,然后想做个点击图片进行预览的效果,猛然发现源码里有PreviewActivity类,因此直接使用PreviewActivity.openActivity()方法打开预览界面,预览正常。但是当点击选择按钮时(相当于取消选择该照片),PagerAdapter异常,下面是完整错误:The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 6, found: 5 Pager id: com.example.admin.imageutil:id/vp_image Pager class: class com.donkingliang.imageselector.view.MyViewPager Problematic adapter: class com.donkingliang.imageselector.adapter.ImagePagerAdapter

一些建議

1.設定為單選模式時 圖片上的圈圈可以消除掉,畢竟點了就進入預覽了..

2.希望可以選擇圖片後,可以選擇 直接按確定取得圖片,也就是說不點選預覽的情況下不進入預覽

謝謝作者開發這麼好用的庫,方便大家。感恩再感恩

根本就用不了,打开就报错

image

Process: com.university.zzz.club, PID: 11710
java.lang.NoSuchFieldError: No static field rv_image of type I in class Lcom/donkingliang/imageselector/R$id; or its superclasses (declaration of 'com.donkingliang.imageselector.R$id' appears in /data/app/com.university.zzz.club-GgMXQEyLHzmOR6yr5HDZJQ==/base.apk!classes2.dex)
at com.donkingliang.imageselector.ImageSelectorActivity.initView(ImageSelectorActivity.java:203)
at com.donkingliang.imageselector.ImageSelectorActivity.onCreate(ImageSelectorActivity.java:183)

点进去id都报红色找不到

关于图片的展示

你好,我使用了你的工具类在mainActivity中使用,可总是执行不到onActivityResult中,图片也没有办法显示,你看是什么问题。

这个案例特别棒!

找了好多类似自定义相册的案例,这个一看就能懂,对我帮助特别大!感谢!

开启选择页面的上下文不只有activity还有可能是fragment,能支持下吗?

ImageSelector.builder()
.useCamera(true)
.setSingle(true)
.setViewImage(true)
.setSelected(imgs)
.start(getActivity(), REQUEST_CODE);
从Fragment中使用这段代码,用的却是activity的startActivityForResult,结果也返回给了父activity而不是发起调用的fragment页面。
可以重载一个start(Fragment frag,int requestCode)方法吗?相应的用frag.startActivityForResult()能更准确地接收结果。

使用1.6.7 发现拍照之后的照片 使用多图片使用问题

在使用1.6.7 拍照之后 在使用图片选择器的时候 由于扫描图片 并没有扫描到Pictures 文件夹下的图片 导致 选择图片 还是可以选择最大图片 也就是说 最大选择三张图片 , 拍照一张图片 然后在图片选择中 并不显示 还可以选择三张。

照片太大,预览的时候无法显示

照片很大,有3兆。在选择图片的时候,缩略图可以查看,但是查看预览的时候,部分低端机无法显示,好一些的手机也需要等待一秒才能看到

如何设置图片过滤功能?

比如说,选择相册时,我只想展示后缀名为 .png、.jpeg、.jpg 的图片,其他类型图片不想展示。

这种情况如何设置?

关于本地图片加载不及时的情况

  1. 图片数量显示不全, 有些文件夹的图片没有显示出来;
  2. APP使用过程中, 同时保存了新的图片到本地, ImageSelector显示不出来;
    3.相机拍摄的png图片显示出来是黑的;

请问一下关于以上两个问题该如何解决, 希望推出新版本, 感谢!;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.