Skip to content

🔥🔥🔥查看大图、查看视频、图片浏览器,完美的甚至完胜微信的打开过渡动画,支持手势放大缩小图片,支持下拉手势返回,支持自定义图片加载库,支持自定义视频库,支持自定义所有UI

License

Notifications You must be signed in to change notification settings

FlyJingFish/OpenImage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

01e5792 · Mar 8, 2025
Dec 15, 2023
Nov 25, 2024
Nov 27, 2024
Nov 25, 2024
Mar 8, 2025
Nov 27, 2024
Feb 17, 2025
Nov 25, 2024
Nov 26, 2024
Aug 24, 2022
Jan 18, 2023
Mar 8, 2025
Feb 28, 2025
Mar 8, 2025
Jul 31, 2022
Jul 31, 2022
Jul 31, 2022
Nov 25, 2024
Mar 8, 2025
Mar 8, 2025

Repository files navigation

OpenImage 图片查看大图库

Maven central GitHub stars GitHub forks GitHub issues GitHub license

属于你的侵入性低的大图查看器,完美的甚至完胜微信的过渡动画,支持自定义视频播放器,也可以自定义加载图片的内核,例如Glide、Coil、Picasso 或其他的

如果帮到你点个star推广给更多人吧~

推荐一个库 AndroidAOP 一个注解就可请求权限,禁止多点,切换线程等等

show

多种场景效果演示(不限于以下几种,更多支持点此查看

RecyclerView场景 聊天页面 打开视频
show show show
朋友圈 快手 WebView
show show show

特色功能

1、支持自定义图片加载引擎

2、支持多种图片缓存模式

3、支持聊天界面的查看大图功能

4、支持任意定制属于你的大图查看页面UI,多种定制方式总有一种适合你(点此查看更多使用说明

5、支持打开后的大图页面数据的增、删、改、查点此查看更多使用说明

6、支持全部 ImageView.ScaleType 显示模式的图片打开大图效果,并且新增startCrop、endCrop、autoStartCenterCrop、autoEndCenterCrop四种显示模式

7、支持图片和视频混合数据

8、支持传入包含图片的 RecyclerViewViewPagerViewPager2ListViewGridView多个ImageView 的调用方式,甚至 WebView,傻瓜式调用,无需关心图片切换后该返回到哪个位置

9、支持Gif图

10、支持长图和长图阅读模式

11、支持显示超大图及放大后的清晰细节图

12、支持视频缩放拖动功能、图片缩放拖动功能

13、支持自定义大图切换效果(PageTransformer)

前言

1、建议使用Glide效果更好,另外建议开启原图缓存(有些版本是自动缓存原图的)Glide通过设置diskCacheStrategy 为DiskCacheStrategy.ALL或DiskCacheStrategy.DATA

2、当然如果您加载的是本地图片可直接忽略第1点

使用步骤

第一步、选择适合你的库

首先、在项目根目录下的build.gradle添加

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

你可以选择下面三种的其中一种,在module下的build.gradle添加。

A、直接引入完整版(同时支持查看图片和视频)

请注意如果使用以下导入方式,如果你的项目组存在GSYVideoPlayer请升级至 10.0.0(从2.3.0开始升级至 10.0.0,之前是8.3.0,并且需要升级AGP到8.1.1以上) 或者更高的版本,否则会冲突

  • 使用 Glide 作为图片加载器,如果你的项目组存在Glide请升级至 4.12.0 或者更高的版本,否则会冲突
//OpenImageFullLib 默认已经包含了OpenImageGlideLib
implementation 'io.github.FlyJingFish.OpenImage:OpenImageFullLib:2.4.1'
  • 使用 Coil 作为图片加载器,如果你的项目组存在Coil请升级至 2.4.0 或者更高的版本,否则会冲突
//OpenImageFullLib 因为已经包含了 OpenImageGlideLib,所以需要排除掉 OpenImageGlideLib,否则会同时存在 Glide 和 Coil
implementation ('io.github.FlyJingFish.OpenImage:OpenImageFullLib:2.4.1'){
    exclude module: 'OpenImageGlideLib'
}
//OpenImageCoilLib 引入Coil(2.4.0)图片引擎
implementation 'io.github.FlyJingFish.OpenImage:OpenImageCoilLib:2.4.1'

B、引入只带有图片引擎的版本(只支持查看图片)

在 Glide 和 Coil 中选一个作为图片加载器

  • 使用 Glide 作为图片加载器,如果你的项目组存在Glide请升级至 4.12.0 或者更高的版本,否则会冲突
//OpenImageGlideLib 引入Glide(4.12.0)图片引擎,没有引入视频播放器;如需定制视频播放功能,详细看Wiki文档,如果不想定制可直接使用上边的库
implementation 'io.github.FlyJingFish.OpenImage:OpenImageGlideLib:2.4.1'
  • 使用 Coil 作为图片加载器,如果你的项目组存在Coil请升级至 2.4.0 或者更高的版本,否则会冲突
//OpenImageCoilLib 引入Coil(2.4.0)图片引擎,没有引入视频播放器;如需定制视频播放功能,详细看Wiki文档,如果不想定制可直接使用上边的库
implementation 'io.github.FlyJingFish.OpenImage:OpenImageCoilLib:2.4.1'

C、引入基础版本(不可以直接查看图片和视频,完全需要自定义)

自己定义加载大图时请注意内存溢出问题,详情可看Wiki文档(点此查看常见问题

//OpenImageLib 是基础库,没有引入图片引擎和视频播放器
//至少需要实现BigImageHelper来定制您的图片引擎,如需定制视频播放功能,详细看Wiki文档
implementation 'io.github.FlyJingFish.OpenImage:OpenImageLib:2.4.1'

第二步. 简单一步调用即可

先确保你有没有添加以下权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.INTERNET" />
    
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />

    <!-- Android 13版本适配,细化存储权限 -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
</manifest>

你可以选择下面两种图片数据的其中一种

A、直接将数据转化为 String 的List (这个方式适合只看图片或视频,不可显示混合数据)

List<String> dataList = new ArrayList<>();
for (ImageEntity data : datas) {
    dataList.add(data.getImageUrl());
}

//在点击时调用(以下以RecyclerView为例介绍)
OpenImage.with(activity)
        //点击ImageView所在的RecyclerView(也支持设置setClickViewPager2,setClickViewPager,setClickGridView,setClickListView,setClickImageView,setClickWebView,setNoneClickView)
        .setClickRecyclerView(recyclerView,new SourceImageViewIdGet() {
           @Override
           public int getImageViewId(OpenImageUrl data, int position) {
               return R.id.iv_image;//点击的ImageView的Id或者切换图片后对应的ImageView的Id
           }
       })
       //点击的ImageView的ScaleType类型(如果设置不对,打开的动画效果将是错误的)
       .setSrcImageViewScaleType(ImageView.ScaleType.CENTER_CROP,true)
       //RecyclerView的数据
       .setImageUrlList(dataList, MediaType.IMAGE)
       //点击的ImageView所在数据的位置
       .setClickPosition(position)
       //开始展示大图
       .show();

在此着重再介绍下 SourceImageViewIdGet 在这是动态获取 ImageView 的Id的,如果你的 RecyclerView(或ViewPager2、ListView、GridView) 展示的图片 Id 出现多个则需根据 getImageViewId 中的 position 或 data 来返回对应的 Id,例如:

new SourceImageViewIdGet() {
   @Override
   public int getImageViewId(OpenImageUrl data, int position) {
        //data 可强转为您传入的数据类型
        MessageBean msgBean = (MessageBean) data;
        //在此视频数据和图片数据的 ImageView 的 Id 不一样(根据您具体情况返回对应的Id即可,以下仅为示例~)
        if (msgBean.type == MessageBean.IMAGE){
            return R.id.iv_image;
        }else {
            return R.id.iv_video;
        }
   }
}

B、在您的数据实体类上实现OpenImageUrl接口(这个方式适合显示图片和视频的混合数据,建议使用这个方式)

PS:列表中展示的图片链接和展示大图时所用链接是不同时(即存在缩略图和原始大图两种链接的情况),这种方式可以有更好的过渡效果

public class ImageEntity implements OpenImageUrl {
    public String photoUrl;//图片大图
    public String smallPhotoUrl;//图片小图
    public String coverUrl;//视频封面大图
    public String smallCoverUrl;//视频封面小图
    public String videoUrl;//视频链接
    public int resouceType; //0图片1视频 

    @Override
    public String getImageUrl() {
        return resouceType == 1 ? coverUrl : photoUrl;//大图链接(或视频的封面大图链接)
    }

    @Override
    public String getVideoUrl() {
        return videoUrl;//视频链接
    }

    @Override
    public String getCoverImageUrl() {//这个代表前边列表展示的图片(即缩略图)
        return resouceType == 1 ? smallCoverUrl : smallPhotoUrl;//封面小图链接(或视频的封面小图链接)
    }

    @Override
    public MediaType getType() {
        return resouceType == 1 ? MediaType.VIDEO : MediaType.IMAGE;//数据是图片还是视频
    }
}

然后调用显示

//在点击时调用(以下以RecyclerView为例介绍)
OpenImage.with(activity)
        //点击ImageView所在的RecyclerView(也支持设置setClickViewPager2,setClickViewPager,setClickGridView,setClickListView,setClickImageView,setClickWebView,setNoneClickView)
        .setClickRecyclerView(recyclerView,new SourceImageViewIdGet() {
           @Override
           public int getImageViewId(OpenImageUrl data, int position) {
               return R.id.iv_image;//点击的ImageView的Id或者切换图片后对应的ImageView的Id
           }
       })
       //点击的ImageView的ScaleType类型(如果设置不对,打开的动画效果将是错误的)
       .setSrcImageViewScaleType(ImageView.ScaleType.CENTER_CROP,true)
       //RecyclerView的数据
       .setImageUrlList(datas)
       //点击的ImageView所在数据的位置
       .setClickPosition(position)
       //开始展示大图
       .show();

如果没有可以传的View(即不使用动画打开大图页面)

//在点击时调用(以下以RecyclerView为例介绍)
OpenImage.with(activity)
        //打开大图页面时没有点击的ImageView则用这个
        .setNoneClickView()
        //图片的数据
        .setImageUrlList(datas)
        //默认展示数据的位置
        .setClickPosition(position)
        //开始展示大图
        .show();

PS.完整调用示例 (点此查看更多使用说明

//在点击时调用,按需使用即可(以下以RecyclerView为例介绍)
OpenImage.with(activity)
         //点击ImageView所在的RecyclerView(也支持设置setClickViewPager2,setClickViewPager,setClickGridView,setClickListView,setClickImageView,setClickWebView)
         .setClickRecyclerView(recyclerView,new SourceImageViewIdGet() {
           @Override
           public int getImageViewId(OpenImageUrl data, int position) {
               return R.id.iv_image;//点击的ImageView的Id或者切换图片后对应的ImageView的Id
           }
        })
        //点击的ImageView的ScaleType类型(如果设置不对,打开的动画效果将是错误的)
        .setSrcImageViewScaleType(ImageView.ScaleType.CENTER_CROP,true)
        //RecyclerView的数据
        .setImageUrlList(datas)
        //点击的ImageView所在数据的位置
        .setClickPosition(position)
        //clickDataPosition 点击的数据所在位置 clickViewPosition 点击的视图所在位置(和上边方法二选一,详细使用方法可看wiki文档)
        //这个方法主要是针对的是像聊天页面那种图文混合的数据,可以看 "聊天页面" Demo
        .setClickPosition(clickDataPosition, clickViewPosition)
        //可不设置(定制页面样式,详细可看Wiki文档)
        .setOpenImageStyle(R.style.DefaultPhotosTheme)
        //设置显示在页面上层的fragment(可不设置)
        .setUpperLayerFragmentCreate(new FriendLayerFragmentCreateImpl(),bundle,false,false)
        //设置自定义的视频播放fragment页面(可不设置)
        .setVideoFragmentCreate(new VideoFragmentCreateImpl())
        //设置加载失败时显示的图片(可不设置)
        .setErrorResId(R.mipmap.ic_launcher)
        //设置退出页面时,如果页面无对应的ImageView则回到点击位置(类似微信聊天页面的效果)(可不设置)
        .setWechatExitFillInEffect(true)
        //设置true后关闭时,将看不到前一页面正在查看的图片(可不设置)
        .setShowSrcImageView(true)
        //设置自定义的大图外壳页面(可不设置)
        .setOpenImageActivityCls(MyBigImageActivity.class)
        //设置切换图片时前一页面跟随滚动(可不设置)
        .setAutoScrollScanPosition(true)
        //设置显示下载按钮(可不设置,默认不显示,打开后默认图片和视频都会显示此按钮)
        .setShowDownload()
        //设置显示关闭按钮(可不设置,默认不显示,打开后默认只在显示图片时显示,因为视频页面默认有返回按钮,如需都要显示可在此基础上传入更多参数)
        .setShowClose()
        //设置画廊效果,参数为左右两侧漏出的宽度(可不设置)
        .setGalleryEffect(10)
        //设置切换图片监听(可不设置)
        .setOnSelectMediaListener(new OnSelectMediaListener() {
            @Override
            public void onSelect(OpenImageUrl openImageUrl, int position) {

            }
        })
        //设置点击监听(可不设置)
        .setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(BaseInnerFragment fragment, OpenImageUrl openImageUrl, int position) {
    
            }
        })
        //设置长按图片监听(可不设置)
        .setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public void onItemLongClick(BaseInnerFragment fragment, OpenImageUrl openImageUrl, int position) {
            
            }
        })
        //设置退出大图页面时的监听(可不设置)
        .setOnExitListener(new OnExitListener() {
            @Override
            public void onExit() {
            
            }
        })
        //设置切换大图时的效果(可不设置,本库中目前只有这一个,如需其他效果可参照ScaleInTransformer自行定义效果)
        .addPageTransformer(new ScaleInTransformer())
        //开始展示大图
        .show();

额外步骤

A、如果您引用的库是 OpenImageLib 您需要实现BigImageHelper接口并设置它,它是加载大图的关键(以下以Glide为例)

(如果您使用的是 OpenImageFullLib 或 OpenImageGlideLib 或 OpenImageCoilLib 则不需要这一步)

自己定义加载大图时请注意内存溢出问题,详情可看Wiki文档(点此查看常见问题

 public class MyApplication extends Application {
     @Override
     public void onCreate() {
         super.onCreate();
         //初始化大图加载器
         OpenImageConfig.getInstance().setBigImageHelper(new BigImageHelperImpl());
     }
 }
 
 public class BigImageHelperImpl implements BigImageHelper {
    @Override
    public void loadImage(Context context, String imageUrl, OnLoadBigImageListener onLoadBigImageListener) {
        //这个地方只是示例,如果你的项目存在超大图,请注意需要自行处理(否则可能内存溢出或崩溃)
        //不想自己搞的,可直接用 OpenImageGlideLib 或 OpenImageFullLib
        RequestOptions requestOptions = new RequestOptions()
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    //这句是为了加载原图,如果你的原图可能是超大图,请注意内存溢出问题,不想自己搞的,可直接用 OpenImageGlideLib 或 OpenImageFullLib
                    .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
                    .format(DecodeFormat.PREFER_RGB_565);
        Glide.with(context)
                    .load(imageUrl).apply(requestOptions).addListener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                    onLoadBigImageListener.onLoadImageFailed();
                    return false;
                }

                @Override
                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                    onLoadBigImageListener.onLoadImageSuccess(resource);
                    return false;
                }
            }).into(new CustomTarget<Drawable>() {
                @Override
                public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {

                }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {

                }
            });

    }

}

B、如果您引用的库是 OpenImageLib 或 OpenImageGlideLib 或 OpenImageCoilLib 需要查看视频的功能,需要以下步骤

(如果您使用的是 OpenImageFullLib 则不需要这一步)

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //初始化视频创建类
        OpenImageConfig.getInstance().setVideoFragmentCreate(new VideoFragmentCreateImpl());
    }
}
public class VideoFragmentCreateImpl implements VideoFragmentCreate {
   @Override
   public BaseFragment createVideoFragment() {
       return new VideoPlayerFragment();
   }
}

public class VideoPlayerFragment extends BaseImageFragment<ENDownloadView> {

   private FragmentVideoBinding binding;
   private String playerKey;
   private boolean isLoadImageFinish;
   protected boolean isPlayed;

   @Override
   protected ImageView getSmallCoverImageView() {//返回小封面图
       return binding.videoPlayer.getSmallCoverImageView();
   }

   @Override
   protected ImageView getPhotoView() {//返回大封面图,必须在小封面图下边
       return binding.videoPlayer.getCoverImageView();
   }

   @Override
   protected ENDownloadView getLoadingView() {//返回loadingView
       return (ENDownloadView) binding.videoPlayer.getLoadingView();
   }

   @Override
   protected void hideLoading(ENDownloadView pbLoading) {//隐藏loading需要特殊处理的重写这个
       super.hideLoading(pbLoading);
       pbLoading.release();
       binding.videoPlayer.getStartButton().setVisibility(View.VISIBLE);
   }

   @Override
   protected void showLoading(ENDownloadView pbLoading) {//显示loading需要特殊处理的重写这个
       super.showLoading(pbLoading);
       pbLoading.start();
       binding.videoPlayer.getStartButton().setVisibility(View.GONE);
   }

   @Override
   public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
       super.onViewCreated(view, savedInstanceState);
       binding.videoPlayer.findViewById(R.id.back).setOnClickListener(v -> close());
       playerKey = binding.videoPlayer.getVideoKey();
       binding.videoPlayer.goneAllWidget();
       isPlayed = false;
   }
   @Override
   protected void onTouchClose(float scale) {//下拉关闭回调
       super.onTouchClose(scale);
       binding.videoPlayer.findViewById(R.id.surface_container).setVisibility(View.GONE);
       binding.videoPlayer.goneAllWidget();
   }

   @Override
   protected void onTouchScale(float scale) {//下拉时回调
       super.onTouchScale(scale);
       binding.videoPlayer.goneAllWidget();
       if (scale == 1){
           binding.videoPlayer.showAllWidget();
       }
   }

   @Override
   protected void loadImageFinish(boolean isLoadImageSuccess) {
       isLoadImageFinish = true;
       play();
   }

   private void play(){
       if (isTransitionEnd && isLoadImageFinish && !isPlayed){//这里可以不等封面图加载完就播放,这个是为了更好的效果
           if (getLifecycle().getCurrentState() == Lifecycle.State.RESUMED){
               toPlay4Resume();
           }else {
               getLifecycle().addObserver(new LifecycleEventObserver() {
                   @Override
                   public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                       if (event == Lifecycle.Event.ON_RESUME){
                           toPlay4Resume();
                           source.getLifecycle().removeObserver(this);
                       }
                   }
               });
           }

           isPlayed = true;
       }
   }

   protected void toPlay4Resume(){
       binding.videoPlayer.playUrl(openImageBean.getVideoUrl());
       binding.videoPlayer.startPlayLogic();
   }

   @Override
   protected void onTransitionEnd() {
       super.onTransitionEnd();
       play();
   }

   @Override
   public void onResume() {
       super.onResume();
       if (playerKey != null) {
           GSYVideoController.resumeByKey(playerKey);
       }
   }

   @Override
   public void onPause() {
       super.onPause();
       if (playerKey != null) {
           GSYVideoController.pauseByKey(playerKey);
       }
   }

   @Override
   public void onDestroyView() {
       super.onDestroyView();
       if (playerKey != null) {
           GSYVideoController.cancelByKeyAndDeleteKey(playerKey);
       }
   }

   @Override
   public View getExitImageView() {//退出页面时需要保证封面图可见
       binding.videoPlayer.getThumbImageViewLayout().setVisibility(View.VISIBLE);
       return super.getExitImageView();
   }
}

点击以下链接查看更多使用说明

点此查看更多使用说明

更新日志

点此查看更新日志

混淆

1、如果您使用的是 OpenImageFullLib 需要遵循以下三方库的规则

GSYVideoPlayer

Glide

2、如果您使用的是 OpenImageGlideLib 需要遵循以下三方库的规则

Glide

3、如果您使用的是 OpenImageCoilLib 需要遵循以下三方库的规则

Coil

4、如果您使用的是 OpenImageLib 则不需要添加任何混淆规则

为了方便我将所有的混淆规则直接粘贴如下:

GSYVideoPlayer 的混淆规则:

-keep class com.shuyu.gsyvideoplayer.video.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.video.**
-keep class com.shuyu.gsyvideoplayer.video.base.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.video.base.**
-keep class com.shuyu.gsyvideoplayer.utils.** { *; }
-dontwarn com.shuyu.gsyvideoplayer.utils.**
-keep class tv.danmaku.ijk.** { *; }
-dontwarn tv.danmaku.ijk.**

-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, java.lang.Boolean);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

Glide 的混淆规则:

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {
 <init>(...);
}
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
  *** rewind();
}

Coil 混淆规则,遵循 Coroutines,OkHttp

# When editing this file, update the following files as well:
# - META-INF/com.android.tools/proguard/coroutines.pro
# - META-INF/com.android.tools/r8/coroutines.pro

# ServiceLoader support
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}

# Most of volatile fields are updated with AFU and should not be mangled
-keepclassmembers class kotlinx.coroutines.** {
    volatile <fields>;
}

# Same story for the standard library's SafeContinuation that also uses AtomicReferenceFieldUpdater
-keepclassmembers class kotlin.coroutines.SafeContinuation {
    volatile <fields>;
}

# These classes are only required by kotlinx.coroutines.debug.AgentPremain, which is only loaded when
# kotlinx-coroutines-core is used as a Java agent, so these are not needed in contexts where ProGuard is used.
-dontwarn java.lang.instrument.ClassFileTransformer
-dontwarn sun.misc.SignalHandler
-dontwarn java.lang.instrument.Instrumentation
-dontwarn sun.misc.Signal

# Only used in `kotlinx.coroutines.internal.ExceptionsConstructor`.
# The case when it is not available is hidden in a `try`-`catch`, as well as a check for Android.
-dontwarn java.lang.ClassValue

# An annotation used for build tooling, won't be directly accessed.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement



# Okhttp3

# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**

# A resource is loaded with a relative path so the package of this class must be preserved.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz

# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*

# OkHttp platform used only on JVM and when Conscrypt and other security providers are available.
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**

版本限制

最低SDK版本:minSdkVersion >= 22

常见问题

点此查看常见问题

Thanks

PhotoView

赞赏

都看到这里了,如果您喜欢 OpenImage,或感觉 OpenImage 帮助到了您,可以点右上角“Star”支持一下,您的支持就是我的动力,谢谢~ 😃

如果感觉 OpenImage 为您节约了大量开发时间、为您的项目增光添彩,您也可以扫描下面的二维码,请作者喝杯咖啡 ☕

联系方式

About

🔥🔥🔥查看大图、查看视频、图片浏览器,完美的甚至完胜微信的打开过渡动画,支持手势放大缩小图片,支持下拉手势返回,支持自定义图片加载库,支持自定义视频库,支持自定义所有UI

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published