├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── demo │ │ ├── MainActivity.java │ │ └── OCApplication.java │ └── res │ ├── layout │ ├── activity_main.xml │ └── demo_photoview.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gif └── display-1.0.4.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── imageviewer ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── imageviewer │ │ ├── adapter │ │ └── ViewpagerAdapter.java │ │ ├── dragable │ │ ├── ElasticDismissListener.java │ │ ├── SwipeDismissTouchListener.java │ │ └── SwipeableFrameLayout.java │ │ ├── helper │ │ ├── ImageLoader.java │ │ ├── ImageTramsform.java │ │ ├── OnDestroyCallback.java │ │ ├── OnImageLongClickListener.java │ │ ├── OnImageSingleClickListener.java │ │ ├── OnLoadListener.java │ │ └── OnPageChangeListener.java │ │ ├── tranformer │ │ ├── ABaseTransformer.java │ │ ├── CubeOutTransformer.java │ │ ├── DefaultTransformer.java │ │ ├── DepthPageTransformer.java │ │ └── ZoomOutTranformer.java │ │ └── view │ │ ├── FixedViewPager.java │ │ └── ImageViewer.java │ └── res │ ├── layout │ ├── fixed_viewpager.xml │ └── switch_photoview.xml │ └── values │ ├── colors.xml │ ├── dimen.xml │ ├── strings.xml │ └── styles.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageViewer 2 | 3 | ## Screenshot 4 | 5 | ![](gif/display-1.0.4.gif) 6 | 7 | ## Usage 8 | 9 | Add it in your root build.gradle at the end of repositories: 10 | 11 | allprojects { 12 | repositories { 13 | ... 14 | maven { url 'https://jitpack.io' } 15 | } 16 | } 17 | 18 | Step 2. Add the dependency 19 | 20 | dependencies { 21 | compile 'com.github.Cloudist:ImageViewer:1.1.5' 22 | } 23 | 24 | ## Sample Code 25 | 26 | ```Java 27 | final ViewpagerCommonAdapter viewpagerCommonAdapter = new ViewpagerCommonAdapter(MainActivity.this); 28 | 29 | viewpagerCommonAdapter.setOnImageSingleClickListener(new OnImageSingleClickListener() { 30 | @Override 31 | public void onImageSingleClick(int position, String path, PhotoView photoView) { 32 | Toast.makeText(MainActivity.this, "onImageSingleClick" + position, Toast.LENGTH_SHORT).show(); 33 | } 34 | }); 35 | 36 | viewpagerCommonAdapter.setOnImageLongClickListener(new OnImageLongClickListener() { 37 | @Override 38 | public boolean onImageLongClick(int position, String path, PhotoView photoView) { 39 | Toast.makeText(MainActivity.this, "onImageLongClick" + position, Toast.LENGTH_SHORT).show(); 40 | return false; 41 | } 42 | }); 43 | 44 | final ImageViewer imageViewer = new ImageViewer.Builder( 45 | new ImageLoader() { 46 | @Override 47 | public void showImage(final int position, String path, ImageView imageView) { 48 | final OnLoadListener loadListener = this.getOnLoadListener(); 49 | final View view = this.getView(); 50 | loadListener.onStart(position); 51 | Glide.with(OCApplication.getContext()) 52 | .load(path) 53 | .listener(new RequestListener() { 54 | @Override 55 | public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { 56 | loadListener.onError(position); 57 | return false; 58 | } 59 | 60 | @Override 61 | public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { 62 | loadListener.onSuccess(position); 63 | return false; 64 | } 65 | }) 66 | .into(imageView); 67 | } 68 | }, 69 | viewpagerCommonAdapter) 70 | .setIndex(2) 71 | .setPaths(paths) 72 | .setTransformerType(ImageViewer.TYPE_CUBEOUT_TRANSFORMER) 73 | .build() 74 | .show(getSupportFragmentManager(), "ImageViewer"); 75 | ``` 76 | 77 | ## Customized Adapter 78 | 79 | ```Java 80 | public class CustomViewpagerAdapter extends ViewpagerAdapter { 81 | 82 | public CustomViewpagerAdapter(Context context) { 83 | super(context); 84 | } 85 | 86 | @Override 87 | protected View initView(ViewGroup container, int position) { 88 | return LayoutInflater.from(mContext).inflate(R.layout.demo_photoview, container, false); 89 | } 90 | 91 | @Override 92 | protected void loadImage(final int position, String path, View view) { 93 | final ImageView imageView = (ImageView) view.findViewById(R.id.image_demo); 94 | //自定义adapter可以在内部直接设置点击事件 95 | imageView.setOnClickListener(new View.OnClickListener() { 96 | @Override 97 | public void onClick(View v) { 98 | Toast.makeText(mContext, "demoOnPhotoTap" + position, Toast.LENGTH_SHORT).show(); 99 | } 100 | }); 101 | 102 | imageView.setOnLongClickListener(new View.OnLongClickListener() { 103 | @Override 104 | public boolean onLongClick(View v) { 105 | Toast.makeText(mContext, "demoOnLongClick" + position, Toast.LENGTH_SHORT).show(); 106 | return false; 107 | } 108 | }); 109 | 110 | imageLoader.showImage(position, path, imageView); 111 | } 112 | 113 | } 114 | ``` 115 | 116 | ## Customized ImageViewer init 117 | 118 | ```Java 119 | new ImageViewer.Builder( 120 | new ImageLoader() { 121 | @Override 122 | public void showImage(int position, String path, ImageView imageView) { 123 | Glide.with(OCApplication.getContext()) 124 | .load(path) 125 | .into(imageView); 126 | } 127 | }, 128 | new CustomViewpagerAdapter(MainActivity.this)) 129 | .setIndex(3) 130 | .setPaths(paths) 131 | .setTransformerType(ImageViewer.TYPE_ZOOMOUT_TRANSFORMER) 132 | .build() 133 | .show(getSupportFragmentManager(), "ImageViewer"); 134 | 135 | ``` 136 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "cn.demo" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.3.1' 28 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 29 | testCompile 'junit:junit:4.12' 30 | compile project(path: ':imageviewer') 31 | compile 'com.github.bumptech.glide:glide:3.7.0' 32 | } 33 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\cloudist\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/cn/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package cn.demo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | import android.widget.Button; 7 | import android.widget.ImageView; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.bumptech.glide.load.resource.drawable.GlideDrawable; 11 | import com.bumptech.glide.request.RequestListener; 12 | import com.bumptech.glide.request.target.Target; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | import cn.imageviewer.adapter.ViewpagerAdapter; 18 | import cn.imageviewer.helper.OnImageLongClickListener; 19 | import cn.imageviewer.helper.OnImageSingleClickListener; 20 | import cn.imageviewer.helper.OnLoadListener; 21 | import cn.imageviewer.helper.ImageLoader; 22 | import cn.imageviewer.view.ImageViewer; 23 | import uk.co.senab.photoview.PhotoView; 24 | 25 | public class MainActivity extends AppCompatActivity { 26 | 27 | List paths; 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_main); 33 | 34 | Button button1 = (Button) findViewById(R.id.button1); 35 | Button button2 = (Button) findViewById(R.id.button2); 36 | 37 | paths = new ArrayList<>(); 38 | paths.add("http://i2.sinaimg.cn/travel/2015/0715/U10172P704DT20150715110013.png"); 39 | paths.add("http://img02.tooopen.com/images/20150628/tooopen_sy_132149827682.jpg"); 40 | paths.add("http://pic.qiantucdn.com/58pic/17/99/58/34R58PICpKy_1024.jpg"); 41 | paths.add("http://tupian.enterdesk.com/2013/mxy/12/07/3/4.jpg"); 42 | paths.add("http://pic.58pic.com/58pic/13/40/15/62958PICTq7_1024.jpg"); 43 | paths.add("http://pic.qiantucdn.com/58pic/11/69/82/58PIC2Q58PICsY9.jpg"); 44 | paths.add("http://img3.3lian.com/2013/v11/41/d/81.jpg"); 45 | 46 | button1.setOnClickListener(new View.OnClickListener() { 47 | @Override 48 | public void onClick(View v) { 49 | // new ImageViewer.Builder( 50 | // new ImageLoader() { 51 | // @Override 52 | // public void showImage(int position, Object path, ImageView imageView) { 53 | // Glide.with(OCApplication.getContext()) 54 | // .load(path) 55 | // .into(imageView); 56 | // } 57 | // }, 58 | // new CustomViewpagerAdapter(MainActivity.this)) 59 | // .setIndex(0) 60 | // .setPaths(paths) 61 | // .build() 62 | // .show(getSupportFragmentManager(), "ImageViewer"); 63 | } 64 | }); 65 | 66 | button2.setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | new ImageViewer.Builder(MainActivity.this, 70 | new ImageLoader() { 71 | @Override 72 | public void showImage(final int position, Object path, ImageView imageView) { 73 | Glide.with(OCApplication.getContext()) 74 | .load(path.toString()) 75 | .into(imageView); 76 | } 77 | }) 78 | .setIndex(2) 79 | .setPaths(paths) 80 | .setTransformerType(ImageViewer.TYPE_CUBEOUT_TRANSFORMER) 81 | .setOnImageLongClickListener(new OnImageLongClickListener() { 82 | @Override 83 | public boolean onImageLongClick(int position, Object path, PhotoView photoView, ImageViewer imageViewer) { 84 | imageViewer.dismiss(); 85 | return false; 86 | } 87 | }) 88 | .build() 89 | .show(getSupportFragmentManager(), "ImageViewer"); 90 | } 91 | }); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/cn/demo/OCApplication.java: -------------------------------------------------------------------------------- 1 | package cn.demo; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | public class OCApplication extends Application { 7 | 8 | 9 | private static Context sContext; 10 | 11 | @Override 12 | public void onCreate() { 13 | super.onCreate(); 14 | sContext = getApplicationContext(); 15 | } 16 | 17 | public static Context getContext() { 18 | return sContext; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 |