diff --git a/build.gradle b/build.gradle index c180dd4b..87790154 100644 --- a/build.gradle +++ b/build.gradle @@ -4,23 +4,25 @@ buildscript { repositories { jcenter() mavenCentral() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.3' - classpath 'me.tatarka:gradle-retrolambda:3.2.5' - classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.5.0' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' + classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'me.tatarka:gradle-retrolambda:3.7.0' + classpath 'com.novoda:bintray-release:0.8.0' } - - - // Exclude the version that the android plugin depends on. - configurations.classpath.exclude group: 'com.android.tools.external.lombok' } allprojects { repositories { jcenter() + mavenCentral() + google() + maven { url "https://jitpack.io" } + } + tasks.withType(Javadoc) { + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 098fb0a2..596b3a4c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#AT +#Mon May 21 14:29:30 CST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/library/build.gradle b/library/build.gradle index 37f3035a..011f0fce 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,21 +1,19 @@ apply plugin: 'com.android.library' apply plugin: 'me.tatarka.retrolambda' -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: "com.jfrog.bintray" - -version = "1.1.3" - +apply plugin: 'com.novoda.bintray-release' +publish { + userOrg = 'donald' + groupId = 'acom.github.DonaldDu' + artifactId = 'RxGalleryFinal' + publishVersion = '1.1.3.4' + artifacts +} android { - compileSdkVersion 25 - buildToolsVersion '25.0.3' - - // compileSdkVersion 24 - // buildToolsVersion '24' - + compileSdkVersion 27 + buildToolsVersion '27.0.3' defaultConfig { minSdkVersion 14 - targetSdkVersion 25 - // targetSdkVersion 24 + targetSdkVersion 27 versionCode 3 versionName version @@ -33,96 +31,18 @@ android { resourcePrefix "gallery_" } - - dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' - compile 'io.reactivex.rxjava2:rxandroid:2.0.1' - compile 'io.reactivex.rxjava2:rxjava:2.1.0' - compile 'com.yalantis:ucrop:2.2.0' - compile 'com.android.support:recyclerview-v7:25.3.1' - compile 'com.android.support:appcompat-v7:25.3.1' - compile "com.android.support:exifinterface:25.3.1" - /* compile 'com.android.support:recyclerview-v7:24.2.0' - compile 'com.android.support:appcompat-v7:24.2.0' - compile "com.android.support:exifinterface:25.1.0"*/ - provided 'com.squareup.picasso:picasso:2.5.2' - provided 'com.facebook.fresco:fresco:1.3.0' - provided 'com.facebook.fresco:animated-gif:1.3.0' - provided 'com.github.bumptech.glide:glide:3.7.0' - provided 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' -} - -//===================================upload jcenter================================================= -def siteUrl = 'https://github.com/FinalTeam/RxGalleryFinal' -def gitUrl = 'https://github.com/FinalTeam/RxGalleryFinal.git' -group = "cn.finalteam.rxgalleryfinal" - -install { - repositories.mavenInstaller { - pom { - project { - packaging 'aar' - - // Add your description here - name 'RxGalleryFinal' - description = 'dujinyang desc' - url siteUrl - - // Set your license - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - developers { - developer { - id 'dujinyang' - name 'dujinyang' - email '309933706@qq.com' - } - } - scm { - connection gitUrl - developerConnection gitUrl - url siteUrl - - } - } - } - } -} - -task sourcesJar(type: Jar) { - from android.sourceSets.main.java.srcDirs - classifier = 'sources' -} - -artifacts { - archives sourcesJar -} - -Properties properties = new Properties() -properties.load(project.rootProject.file('local.properties').newDataInputStream()) - -bintray { - user = properties.getProperty("bintray.user") - key = properties.getProperty("bintray.apikey") - - configurations = ['archives'] - pkg { - repo = "maven" - name = "RxGalleryFinal" - websiteUrl = siteUrl - vcsUrl = gitUrl - licenses = ["Apache-2.0"] - publish = true - version { - gpg { - passphrase = properties.getProperty("bintray.gpg.password") - } - } - } -} + implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.9.0' + api 'io.reactivex.rxjava2:rxandroid:2.0.2' + api 'com.github.yalantis:ucrop:2.2.2' + compileOnly 'com.android.support:appcompat-v7:27.1.1' + compileOnly 'com.android.support:recyclerview-v7:27.1.1' + compileOnly 'com.android.support:exifinterface:27.1.1' + compileOnly 'com.squareup.picasso:picasso:2.5.2' + compileOnly 'com.facebook.fresco:fresco:1.9.0' + compileOnly 'com.facebook.fresco:animated-gif:1.9.0' + compileOnly 'com.github.bumptech.glide:glide:3.7.0' + compileOnly 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' +} \ No newline at end of file diff --git a/library/src/main/java/cn/finalteam/rxgalleryfinal/Configuration.java b/library/src/main/java/cn/finalteam/rxgalleryfinal/Configuration.java index 9a9df6d6..4c2d517f 100644 --- a/library/src/main/java/cn/finalteam/rxgalleryfinal/Configuration.java +++ b/library/src/main/java/cn/finalteam/rxgalleryfinal/Configuration.java @@ -71,7 +71,7 @@ public Configuration[] newArray(int size) { //等比缩放值表,默认1:1,3:4,原图比例,3:2,16:9 private AspectRatio[] aspectRatio; //是否允许改变裁剪大小 - private boolean freestyleCropEnabled = OverlayView.DEFAULT_FREESTYLE_CROP_ENABLED; + private boolean freestyleCropEnabled = false; //是否显示裁剪框半透明椭圆浮层 private boolean ovalDimmedLayer = OverlayView.DEFAULT_CIRCLE_DIMMED_LAYER;//DEFAULT_OVAL_DIMMED_LAYER private int maxResultWidth; diff --git a/library/src/main/java/cn/finalteam/rxgalleryfinal/ui/adapter/MediaPreviewAdapter.java b/library/src/main/java/cn/finalteam/rxgalleryfinal/ui/adapter/MediaPreviewAdapter.java index 5dc09937..a7278a3c 100644 --- a/library/src/main/java/cn/finalteam/rxgalleryfinal/ui/adapter/MediaPreviewAdapter.java +++ b/library/src/main/java/cn/finalteam/rxgalleryfinal/ui/adapter/MediaPreviewAdapter.java @@ -1,16 +1,17 @@ package cn.finalteam.rxgalleryfinal.ui.adapter; import android.graphics.drawable.Drawable; -import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; +import com.davemorrissey.labs.subscaleview.ImageSource; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; + import java.util.List; import cn.finalteam.rxgalleryfinal.Configuration; import cn.finalteam.rxgalleryfinal.R; import cn.finalteam.rxgalleryfinal.bean.MediaBean; -import uk.co.senab.photoview.PhotoView; /** * Desction: @@ -46,17 +47,9 @@ public View getView(int position, View convertView, ViewGroup container) { if (convertView == null) { convertView = View.inflate(container.getContext(), R.layout.gallery_media_image_preview_item, null); } - PhotoView ivImage = (PhotoView) convertView.findViewById(R.id.iv_media_image); - String path = null; - if (mediaBean.getWidth() > 1200 || mediaBean.getHeight() > 1200) { - path = mediaBean.getThumbnailBigPath(); - } - if (TextUtils.isEmpty(path)) { - path = mediaBean.getOriginalPath(); - } + SubsamplingScaleImageView ivImage = (SubsamplingScaleImageView) convertView; ivImage.setBackgroundColor(mPageColor); - mConfiguration.getImageLoader().displayImage(container.getContext(), path, ivImage, mDefaultImage, mConfiguration.getImageConfig(), - false, mConfiguration.isPlayGif(), mScreenWidth, mScreenHeight, mediaBean.getOrientation()); + ivImage.setImage(ImageSource.uri(mediaBean.getOriginalPath())); return convertView; } diff --git a/library/src/main/java/uk/co/senab/photoview/Compat.java b/library/src/main/java/uk/co/senab/photoview/Compat.java deleted file mode 100755 index 05f81d70..00000000 --- a/library/src/main/java/uk/co/senab/photoview/Compat.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview; - -import android.annotation.TargetApi; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.view.MotionEvent; -import android.view.View; - -public class Compat { - - private static final int SIXTY_FPS_INTERVAL = 1000 / 60; - - public static void postOnAnimation(View view, Runnable runnable) { - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { - postOnAnimationJellyBean(view, runnable); - } else { - view.postDelayed(runnable, SIXTY_FPS_INTERVAL); - } - } - - @TargetApi(16) - private static void postOnAnimationJellyBean(View view, Runnable runnable) { - view.postOnAnimation(runnable); - } - - public static int getPointerIndex(int action) { - return getPointerIndexHoneyComb(action); - } - - @SuppressWarnings("deprecation") - @TargetApi(VERSION_CODES.ECLAIR) - private static int getPointerIndexEclair(int action) { - return (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; - } - - @TargetApi(VERSION_CODES.HONEYCOMB) - private static int getPointerIndexHoneyComb(int action) { - return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - -} diff --git a/library/src/main/java/uk/co/senab/photoview/DefaultOnDoubleTapListener.java b/library/src/main/java/uk/co/senab/photoview/DefaultOnDoubleTapListener.java deleted file mode 100755 index 06c58be3..00000000 --- a/library/src/main/java/uk/co/senab/photoview/DefaultOnDoubleTapListener.java +++ /dev/null @@ -1,100 +0,0 @@ -package uk.co.senab.photoview; - -import android.graphics.RectF; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.widget.ImageView; - -/** - * Provided default implementation of GestureDetector.OnDoubleTapListener, to be overriden with custom behavior, if needed - *

 

- * To be used via {@link PhotoViewAttacher#setOnDoubleTapListener(GestureDetector.OnDoubleTapListener)} - */ -public class DefaultOnDoubleTapListener implements GestureDetector.OnDoubleTapListener { - - private PhotoViewAttacher photoViewAttacher; - - /** - * Default constructor - * - * @param photoViewAttacher PhotoViewAttacher to bind to - */ - public DefaultOnDoubleTapListener(PhotoViewAttacher photoViewAttacher) { - setPhotoViewAttacher(photoViewAttacher); - } - - /** - * Allows to change PhotoViewAttacher within range of single instance - * - * @param newPhotoViewAttacher PhotoViewAttacher to bind to - */ - public void setPhotoViewAttacher(PhotoViewAttacher newPhotoViewAttacher) { - this.photoViewAttacher = newPhotoViewAttacher; - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent e) { - if (this.photoViewAttacher == null) - return false; - - ImageView imageView = photoViewAttacher.getImageView(); - - if (null != photoViewAttacher.getOnPhotoTapListener()) { - final RectF displayRect = photoViewAttacher.getDisplayRect(); - - if (null != displayRect) { - final float x = e.getX(), y = e.getY(); - - // Check to see if the user tapped on the photo - if (displayRect.contains(x, y)) { - - float xResult = (x - displayRect.left) - / displayRect.width(); - float yResult = (y - displayRect.top) - / displayRect.height(); - - photoViewAttacher.getOnPhotoTapListener().onPhotoTap(imageView, xResult, yResult); - return true; - } else { - photoViewAttacher.getOnPhotoTapListener().onOutsidePhotoTap(); - } - } - } - if (null != photoViewAttacher.getOnViewTapListener()) { - photoViewAttacher.getOnViewTapListener().onViewTap(imageView, e.getX(), e.getY()); - } - - return false; - } - - @Override - public boolean onDoubleTap(MotionEvent ev) { - if (photoViewAttacher == null) - return false; - - try { - float scale = photoViewAttacher.getScale(); - float x = ev.getX(); - float y = ev.getY(); - - if (scale < photoViewAttacher.getMediumScale()) { - photoViewAttacher.setScale(photoViewAttacher.getMediumScale(), x, y, true); - } else if (scale >= photoViewAttacher.getMediumScale() && scale < photoViewAttacher.getMaximumScale()) { - photoViewAttacher.setScale(photoViewAttacher.getMaximumScale(), x, y, true); - } else { - photoViewAttacher.setScale(photoViewAttacher.getMinimumScale(), x, y, true); - } - } catch (ArrayIndexOutOfBoundsException e) { - // Can sometimes happen when getX() and getY() is called - } - - return true; - } - - @Override - public boolean onDoubleTapEvent(MotionEvent e) { - // Wait for the confirmed onDoubleTap() instead - return false; - } - -} diff --git a/library/src/main/java/uk/co/senab/photoview/IPhotoView.java b/library/src/main/java/uk/co/senab/photoview/IPhotoView.java deleted file mode 100755 index fcf01518..00000000 --- a/library/src/main/java/uk/co/senab/photoview/IPhotoView.java +++ /dev/null @@ -1,372 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview; - -import android.graphics.Bitmap; -import android.graphics.Matrix; -import android.graphics.RectF; -import android.view.GestureDetector; -import android.view.View; -import android.widget.ImageView; - - -public interface IPhotoView { - - float DEFAULT_MAX_SCALE = 3.0f; - float DEFAULT_MID_SCALE = 1.75f; - float DEFAULT_MIN_SCALE = 1.0f; - int DEFAULT_ZOOM_DURATION = 200; - - /** - * Returns true if the PhotoView is set to allow zooming of Photos. - * - * @return true if the PhotoView allows zooming. - */ - boolean canZoom(); - - /** - * Gets the Display Rectangle of the currently displayed Drawable. The Rectangle is relative to - * this View and includes all scaling and translations. - * - * @return - RectF of Displayed Drawable - */ - RectF getDisplayRect(); - - /** - * Sets the Display Matrix of the currently displayed Drawable. The Rectangle is considered - * relative to this View and includes all scaling and translations. - * - * @param finalMatrix target matrix to set PhotoView to - * @return - true if rectangle was applied successfully - */ - boolean setDisplayMatrix(Matrix finalMatrix); - - /** - * Gets the Display Matrix of the currently displayed Drawable. The Rectangle is considered - * relative to this View and includes all scaling and translations. - * - * @return copy of current Display Matrix - */ - Matrix getDisplayMatrix(); - - /** - * Copies the Display Matrix of the currently displayed Drawable. The Rectangle is considered - * relative to this View and includes all scaling and translations. - * - * @param matrix target matrix to copy to - */ - void getDisplayMatrix(Matrix matrix); - - /** - * Use {@link #getMinimumScale()} instead, this will be removed in future release - * - * @return The current minimum scale level. What this value represents depends on the current - * {@link ImageView.ScaleType}. - */ - @Deprecated - float getMinScale(); - - /** - * Use {@link #setMinimumScale(float minimumScale)} instead, this will be removed in future - * release - *

 

- * Sets the minimum scale level. What this value represents depends on the current {@link - * ImageView.ScaleType}. - * - * @param minScale minimum allowed scale - */ - @Deprecated - void setMinScale(float minScale); - - /** - * @return The current minimum scale level. What this value represents depends on the current - * {@link ImageView.ScaleType}. - */ - float getMinimumScale(); - - /** - * Sets the minimum scale level. What this value represents depends on the current {@link - * ImageView.ScaleType}. - * - * @param minimumScale minimum allowed scale - */ - void setMinimumScale(float minimumScale); - - /** - * Use {@link #getMediumScale()} instead, this will be removed in future release - * - * @return The current middle scale level. What this value represents depends on the current - * {@link ImageView.ScaleType}. - */ - @Deprecated - float getMidScale(); - - /** - * Use {@link #setMediumScale(float mediumScale)} instead, this will be removed in future - * release - *

 

- * Sets the middle scale level. What this value represents depends on the current {@link - * ImageView.ScaleType}. - * - * @param midScale medium scale preset - */ - @Deprecated - void setMidScale(float midScale); - - /** - * @return The current medium scale level. What this value represents depends on the current - * {@link ImageView.ScaleType}. - */ - float getMediumScale(); - - /** - * Sets the medium scale level. What this value represents depends on the current {@link ImageView.ScaleType}. - * - * @param mediumScale medium scale preset - */ - void setMediumScale(float mediumScale); - - /** - * Use {@link #getMaximumScale()} instead, this will be removed in future release - * - * @return The current maximum scale level. What this value represents depends on the current - * {@link ImageView.ScaleType}. - */ - @Deprecated - float getMaxScale(); - - /** - * Use {@link #setMaximumScale(float maximumScale)} instead, this will be removed in future - * release - *

 

- * Sets the maximum scale level. What this value represents depends on the current {@link - * ImageView.ScaleType}. - * - * @param maxScale maximum allowed scale preset - */ - @Deprecated - void setMaxScale(float maxScale); - - /** - * @return The current maximum scale level. What this value represents depends on the current - * {@link ImageView.ScaleType}. - */ - float getMaximumScale(); - - /** - * Sets the maximum scale level. What this value represents depends on the current {@link - * ImageView.ScaleType}. - * - * @param maximumScale maximum allowed scale preset - */ - void setMaximumScale(float maximumScale); - - /** - * Returns the current scale value - * - * @return float - current scale value - */ - float getScale(); - - /** - * Changes the current scale to the specified value. - * - * @param scale - Value to scale to - */ - void setScale(float scale); - - /** - * Return the current scale type in use by the ImageView. - * - * @return current ImageView.ScaleType - */ - ImageView.ScaleType getScaleType(); - - /** - * Controls how the image should be resized or moved to match the size of the ImageView. Any - * scaling or panning will happen within the confines of this {@link - * ImageView.ScaleType}. - * - * @param scaleType - The desired scaling mode. - */ - void setScaleType(ImageView.ScaleType scaleType); - - /** - * Whether to allow the ImageView's parent to intercept the touch event when the photo is scroll - * to it's horizontal edge. - * - * @param allow whether to allow intercepting by parent element or not - */ - void setAllowParentInterceptOnEdge(boolean allow); - - /** - * Allows to set all three scale levels at once, so you don't run into problem with setting - * medium/minimum scale before the maximum one - * - * @param minimumScale minimum allowed scale - * @param mediumScale medium allowed scale - * @param maximumScale maximum allowed scale preset - */ - void setScaleLevels(float minimumScale, float mediumScale, float maximumScale); - - /** - * Register a callback to be invoked when the Photo displayed by this view is long-pressed. - * - * @param listener - Listener to be registered. - */ - void setOnLongClickListener(View.OnLongClickListener listener); - - /** - * Register a callback to be invoked when the Matrix has changed for this View. An example would - * be the user panning or scaling the Photo. - * - * @param listener - Listener to be registered. - */ - void setOnMatrixChangeListener(PhotoViewAttacher.OnMatrixChangedListener listener); - - /** - * PhotoViewAttacher.OnPhotoTapListener reference should be stored in a variable instead, this - * will be removed in future release. - *

 

- * Returns a listener to be invoked when the Photo displayed by this View is tapped with a - * single tap. - * - * @return PhotoViewAttacher.OnPhotoTapListener currently set, may be null - */ - @Deprecated - PhotoViewAttacher.OnPhotoTapListener getOnPhotoTapListener(); - - /** - * Register a callback to be invoked when the Photo displayed by this View is tapped with a - * single tap. - * - * @param listener - Listener to be registered. - */ - void setOnPhotoTapListener(PhotoViewAttacher.OnPhotoTapListener listener); - - /** - * Enables rotation via PhotoView internal functions. - * - * @param rotationDegree - Degree to rotate PhotoView to, should be in range 0 to 360 - */ - void setRotationTo(float rotationDegree); - - /** - * Enables rotation via PhotoView internal functions. - * - * @param rotationDegree - Degree to rotate PhotoView by, should be in range 0 to 360 - */ - void setRotationBy(float rotationDegree); - - /** - * PhotoViewAttacher.OnViewTapListener reference should be stored in a variable instead, this - * will be removed in future release. - *

 

- * Returns a callback listener to be invoked when the View is tapped with a single tap. - * - * @return PhotoViewAttacher.OnViewTapListener currently set, may be null - */ - @Deprecated - PhotoViewAttacher.OnViewTapListener getOnViewTapListener(); - - /** - * Register a callback to be invoked when the View is tapped with a single tap. - * - * @param listener - Listener to be registered. - */ - void setOnViewTapListener(PhotoViewAttacher.OnViewTapListener listener); - - /** - * Changes the current scale to the specified value. - * - * @param scale - Value to scale to - * @param animate - Whether to animate the scale - */ - void setScale(float scale, boolean animate); - - /** - * Changes the current scale to the specified value, around the given focal point. - * - * @param scale - Value to scale to - * @param focalX - X Focus Point - * @param focalY - Y Focus Point - * @param animate - Whether to animate the scale - */ - void setScale(float scale, float focalX, float focalY, boolean animate); - - /** - * Allows you to enable/disable the zoom functionality on the ImageView. When disable the - * ImageView reverts to using the FIT_CENTER matrix. - * - * @param zoomable - Whether the zoom functionality is enabled. - */ - void setZoomable(boolean zoomable); - - /** - * Enables rotation via PhotoView internal functions. Name is chosen so it won't collide with - * View.setRotation(float) in API since 11 - * - * @param rotationDegree - Degree to rotate PhotoView to, should be in range 0 to 360 - * @deprecated use {@link #setRotationTo(float)} - */ - void setPhotoViewRotation(float rotationDegree); - - /** - * Extracts currently visible area to Bitmap object, if there is no image loaded yet or the - * ImageView is already destroyed, returns {@code null} - * - * @return currently visible area as bitmap or null - */ - Bitmap getVisibleRectangleBitmap(); - - /** - * Allows to change zoom transition speed, default value is 200 (PhotoViewAttacher.DEFAULT_ZOOM_DURATION). - * Will default to 200 if provided negative value - * - * @param milliseconds duration of zoom interpolation - */ - void setZoomTransitionDuration(int milliseconds); - - /** - * Will return instance of IPhotoView (eg. PhotoViewAttacher), can be used to provide better - * integration - * - * @return IPhotoView implementation instance if available, null if not - */ - IPhotoView getIPhotoViewImplementation(); - - /** - * Sets custom double tap listener, to intercept default given functions. To reset behavior to - * default, you can just pass in "null" or public field of PhotoViewAttacher.defaultOnDoubleTapListener - * - * @param newOnDoubleTapListener custom OnDoubleTapListener to be set on ImageView - */ - void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener); - - /** - * Will report back about scale changes - * - * @param onScaleChangeListener OnScaleChangeListener instance - */ - void setOnScaleChangeListener(PhotoViewAttacher.OnScaleChangeListener onScaleChangeListener); - - /** - * Will report back about fling(single touch) - * - * @param onSingleFlingListener OnSingleFlingListener instance - */ - void setOnSingleFlingListener(PhotoViewAttacher.OnSingleFlingListener onSingleFlingListener); -} diff --git a/library/src/main/java/uk/co/senab/photoview/PhotoView.java b/library/src/main/java/uk/co/senab/photoview/PhotoView.java deleted file mode 100755 index bb05bc2c..00000000 --- a/library/src/main/java/uk/co/senab/photoview/PhotoView.java +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Matrix; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.util.AttributeSet; -import android.view.GestureDetector; - -import cn.finalteam.rxgalleryfinal.ui.widget.FixImageView; -import uk.co.senab.photoview.PhotoViewAttacher.OnMatrixChangedListener; -import uk.co.senab.photoview.PhotoViewAttacher.OnPhotoTapListener; -import uk.co.senab.photoview.PhotoViewAttacher.OnViewTapListener; - -public class PhotoView extends FixImageView implements IPhotoView { - - private PhotoViewAttacher mAttacher; - - private ScaleType mPendingScaleType; - - public PhotoView(Context context) { - this(context, null); - } - - public PhotoView(Context context, AttributeSet attr) { - this(context, attr, 0); - } - - public PhotoView(Context context, AttributeSet attr, int defStyle) { - super(context, attr, defStyle); - super.setScaleType(ScaleType.MATRIX); - init(); - } - - protected void init() { - if (null == mAttacher || null == mAttacher.getImageView()) { - mAttacher = new PhotoViewAttacher(this); - } - - if (null != mPendingScaleType) { - setScaleType(mPendingScaleType); - mPendingScaleType = null; - } - } - - /** - * @deprecated use {@link #setRotationTo(float)} - */ - @Override - public void setPhotoViewRotation(float rotationDegree) { - mAttacher.setRotationTo(rotationDegree); - } - - @Override - public void setRotationTo(float rotationDegree) { - mAttacher.setRotationTo(rotationDegree); - } - - @Override - public void setRotationBy(float rotationDegree) { - mAttacher.setRotationBy(rotationDegree); - } - - @Override - public boolean canZoom() { - return mAttacher.canZoom(); - } - - @Override - public RectF getDisplayRect() { - return mAttacher.getDisplayRect(); - } - - @Override - public Matrix getDisplayMatrix() { - return mAttacher.getDisplayMatrix(); - } - - @Override - public void getDisplayMatrix(Matrix matrix) { - mAttacher.getDisplayMatrix(matrix); - } - - @Override - public boolean setDisplayMatrix(Matrix finalRectangle) { - return mAttacher.setDisplayMatrix(finalRectangle); - } - - @Override - @Deprecated - public float getMinScale() { - return getMinimumScale(); - } - - @Override - @Deprecated - public void setMinScale(float minScale) { - setMinimumScale(minScale); - } - - @Override - public float getMinimumScale() { - return mAttacher.getMinimumScale(); - } - - @Override - public void setMinimumScale(float minimumScale) { - mAttacher.setMinimumScale(minimumScale); - } - - @Override - @Deprecated - public float getMidScale() { - return getMediumScale(); - } - - @Override - @Deprecated - public void setMidScale(float midScale) { - setMediumScale(midScale); - } - - @Override - public float getMediumScale() { - return mAttacher.getMediumScale(); - } - - @Override - public void setMediumScale(float mediumScale) { - mAttacher.setMediumScale(mediumScale); - } - - @Override - @Deprecated - public float getMaxScale() { - return getMaximumScale(); - } - - @Override - @Deprecated - public void setMaxScale(float maxScale) { - setMaximumScale(maxScale); - } - - @Override - public float getMaximumScale() { - return mAttacher.getMaximumScale(); - } - - @Override - public void setMaximumScale(float maximumScale) { - mAttacher.setMaximumScale(maximumScale); - } - - @Override - public float getScale() { - return mAttacher.getScale(); - } - - @Override - public void setScale(float scale) { - mAttacher.setScale(scale); - } - - @Override - public ScaleType getScaleType() { - return mAttacher.getScaleType(); - } - - @Override - public void setScaleType(ScaleType scaleType) { - if (null != mAttacher) { - mAttacher.setScaleType(scaleType); - } else { - mPendingScaleType = scaleType; - } - } - - @Override - public void setAllowParentInterceptOnEdge(boolean allow) { - mAttacher.setAllowParentInterceptOnEdge(allow); - } - - @Override - public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) { - mAttacher.setScaleLevels(minimumScale, mediumScale, maximumScale); - } - - @Override - // setImageBitmap calls through to this method - public void setImageDrawable(Drawable drawable) { - super.setImageDrawable(drawable); - if (null != mAttacher) { - mAttacher.update(); - } - } - - @Override - public void setImageResource(int resId) { - super.setImageResource(resId); - if (null != mAttacher) { - mAttacher.update(); - } - } - - @Override - public void setImageURI(Uri uri) { - super.setImageURI(uri); - if (null != mAttacher) { - mAttacher.update(); - } - } - - @Override - public void setOnMatrixChangeListener(OnMatrixChangedListener listener) { - mAttacher.setOnMatrixChangeListener(listener); - } - - @Override - public void setOnLongClickListener(OnLongClickListener l) { - mAttacher.setOnLongClickListener(l); - } - - @Override - @Deprecated - public OnPhotoTapListener getOnPhotoTapListener() { - return mAttacher.getOnPhotoTapListener(); - } - - @Override - public void setOnPhotoTapListener(OnPhotoTapListener listener) { - mAttacher.setOnPhotoTapListener(listener); - } - - @Override - @Deprecated - public OnViewTapListener getOnViewTapListener() { - return mAttacher.getOnViewTapListener(); - } - - @Override - public void setOnViewTapListener(OnViewTapListener listener) { - mAttacher.setOnViewTapListener(listener); - } - - @Override - public void setScale(float scale, boolean animate) { - mAttacher.setScale(scale, animate); - } - - @Override - public void setScale(float scale, float focalX, float focalY, boolean animate) { - mAttacher.setScale(scale, focalX, focalY, animate); - } - - @Override - public void setZoomable(boolean zoomable) { - mAttacher.setZoomable(zoomable); - } - - @Override - public Bitmap getVisibleRectangleBitmap() { - return mAttacher.getVisibleRectangleBitmap(); - } - - @Override - public void setZoomTransitionDuration(int milliseconds) { - mAttacher.setZoomTransitionDuration(milliseconds); - } - - @Override - public IPhotoView getIPhotoViewImplementation() { - return mAttacher; - } - - @Override - public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener) { - mAttacher.setOnDoubleTapListener(newOnDoubleTapListener); - } - - @Override - public void setOnScaleChangeListener(PhotoViewAttacher.OnScaleChangeListener onScaleChangeListener) { - mAttacher.setOnScaleChangeListener(onScaleChangeListener); - } - - @Override - public void setOnSingleFlingListener(PhotoViewAttacher.OnSingleFlingListener onSingleFlingListener) { - mAttacher.setOnSingleFlingListener(onSingleFlingListener); - } - - @Override - protected void onDetachedFromWindow() { - mAttacher.cleanup(); - super.onDetachedFromWindow(); - } - - @Override - protected void onAttachedToWindow() { - init(); - super.onAttachedToWindow(); - } -} \ No newline at end of file diff --git a/library/src/main/java/uk/co/senab/photoview/PhotoViewAttacher.java b/library/src/main/java/uk/co/senab/photoview/PhotoViewAttacher.java deleted file mode 100644 index 160f340c..00000000 --- a/library/src/main/java/uk/co/senab/photoview/PhotoViewAttacher.java +++ /dev/null @@ -1,1198 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Matrix; -import android.graphics.Matrix.ScaleToFit; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.support.v4.view.MotionEventCompat; -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnLongClickListener; -import android.view.ViewParent; -import android.view.ViewTreeObserver; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.Interpolator; -import android.widget.ImageView; -import android.widget.ImageView.ScaleType; - -import java.lang.ref.WeakReference; - -import cn.finalteam.rxgalleryfinal.utils.Logger; -import uk.co.senab.photoview.gestures.OnGestureListener; -import uk.co.senab.photoview.gestures.VersionedGestureDetector; -import uk.co.senab.photoview.scrollerproxy.ScrollerProxy; - -import static android.view.MotionEvent.ACTION_CANCEL; -import static android.view.MotionEvent.ACTION_DOWN; -import static android.view.MotionEvent.ACTION_UP; - -public class PhotoViewAttacher implements IPhotoView, View.OnTouchListener, - OnGestureListener, - ViewTreeObserver.OnGlobalLayoutListener { - - static final int EDGE_NONE = -1; - static final int EDGE_LEFT = 0; - static final int EDGE_RIGHT = 1; - static final int EDGE_BOTH = 2; - private static final String LOG_TAG = "PhotoViewAttacher"; - // let debug flag be dynamic, but still Proguard can be used to remove from - // release builds - private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG); - static int SINGLE_TOUCH = 1; - // These are set so we don't keep allocating them on the heap - private final Matrix mBaseMatrix = new Matrix(); - private final Matrix mDrawMatrix = new Matrix(); - private final Matrix mSuppMatrix = new Matrix(); - private final RectF mDisplayRect = new RectF(); - private final float[] mMatrixValues = new float[9]; - int ZOOM_DURATION = DEFAULT_ZOOM_DURATION; - private Interpolator mInterpolator = new AccelerateDecelerateInterpolator(); - private float mMinScale = DEFAULT_MIN_SCALE; - private float mMidScale = DEFAULT_MID_SCALE; - private float mMaxScale = DEFAULT_MAX_SCALE; - private boolean mAllowParentInterceptOnEdge = true; - private boolean mBlockParentIntercept = false; - private WeakReference mImageView; - // Gesture Detectors - private GestureDetector mGestureDetector; - private uk.co.senab.photoview.gestures.GestureDetector mScaleDragDetector; - // Listeners - private OnMatrixChangedListener mMatrixChangeListener; - private OnPhotoTapListener mPhotoTapListener; - private OnViewTapListener mViewTapListener; - private OnLongClickListener mLongClickListener; - private OnScaleChangeListener mScaleChangeListener; - private OnSingleFlingListener mSingleFlingListener; - private int mIvTop, mIvRight, mIvBottom, mIvLeft; - private FlingRunnable mCurrentFlingRunnable; - private int mScrollEdge = EDGE_BOTH; - private float mBaseRotation; - private boolean mZoomEnabled; - private ScaleType mScaleType = ScaleType.FIT_CENTER; - - public PhotoViewAttacher(ImageView imageView) { - this(imageView, true); - } - - public PhotoViewAttacher(ImageView imageView, boolean zoomable) { - mImageView = new WeakReference<>(imageView); - - imageView.setDrawingCacheEnabled(true); - imageView.setOnTouchListener(this); - - ViewTreeObserver observer = imageView.getViewTreeObserver(); - if (null != observer) - observer.addOnGlobalLayoutListener(this); - - // Make sure we using MATRIX Scale Type - setImageViewScaleTypeMatrix(imageView); - - if (imageView.isInEditMode()) { - return; - } - // Create Gesture Detectors... - mScaleDragDetector = VersionedGestureDetector.newInstance( - imageView.getContext(), this); - - mGestureDetector = new GestureDetector(imageView.getContext(), - new GestureDetector.SimpleOnGestureListener() { - - // forward long click listener - @Override - public void onLongPress(MotionEvent e) { - if (null != mLongClickListener) { - mLongClickListener.onLongClick(getImageView()); - } - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, - float velocityX, float velocityY) { - if (mSingleFlingListener != null) { - if (getScale() > DEFAULT_MIN_SCALE) { - return false; - } - - if (MotionEventCompat.getPointerCount(e1) > SINGLE_TOUCH - || MotionEventCompat.getPointerCount(e2) > SINGLE_TOUCH) { - return false; - } - - return mSingleFlingListener.onFling(e1, e2, velocityX, velocityY); - } - return false; - } - }); - - mGestureDetector.setOnDoubleTapListener(new DefaultOnDoubleTapListener(this)); - mBaseRotation = 0.0f; - - // Finally, update the UI so that we're zoomable - setZoomable(zoomable); - } - - private static void checkZoomLevels(float minZoom, float midZoom, - float maxZoom) { - if (minZoom >= midZoom) { - throw new IllegalArgumentException( - "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value"); - } else if (midZoom >= maxZoom) { - throw new IllegalArgumentException( - "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value"); - } - } - - /** - * @return true if the ImageView exists, and it's Drawable exists - */ - private static boolean hasDrawable(ImageView imageView) { - return null != imageView && null != imageView.getDrawable(); - } - - /** - * @return true if the ScaleType is supported. - */ - private static boolean isSupportedScaleType(final ScaleType scaleType) { - if (null == scaleType) { - return false; - } - - switch (scaleType) { - case MATRIX: - throw new IllegalArgumentException(scaleType.name() - + " is not supported in PhotoView"); - - default: - return true; - } - } - - /** - * Set's the ImageView's ScaleType to Matrix. - */ - private static void setImageViewScaleTypeMatrix(ImageView imageView) { - /** - * PhotoView sets it's own ScaleType to Matrix, then diverts all calls - * setScaleType to this.setScaleType automatically. - */ - if (null != imageView && !(imageView instanceof IPhotoView)) { - if (!ScaleType.MATRIX.equals(imageView.getScaleType())) { - imageView.setScaleType(ScaleType.MATRIX); - } - } - } - - @Override - public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener) { - if (newOnDoubleTapListener != null) { - this.mGestureDetector.setOnDoubleTapListener(newOnDoubleTapListener); - } else { - this.mGestureDetector.setOnDoubleTapListener(new DefaultOnDoubleTapListener(this)); - } - } - - @Override - public void setOnScaleChangeListener(OnScaleChangeListener onScaleChangeListener) { - this.mScaleChangeListener = onScaleChangeListener; - } - - @Override - public void setOnSingleFlingListener(OnSingleFlingListener onSingleFlingListener) { - this.mSingleFlingListener = onSingleFlingListener; - } - - @Override - public boolean canZoom() { - return mZoomEnabled; - } - - /** - * Clean-up the resources attached to this object. This needs to be called when the ImageView is - * no longer used. A good example is from {@link View#onDetachedFromWindow()} or - * from {@link android.app.Activity#onDestroy()}. This is automatically called if you are using - * {@link PhotoView}. - */ - @SuppressWarnings("deprecation") - public void cleanup() { - if (null == mImageView) { - return; // cleanup already done - } - - final ImageView imageView = mImageView.get(); - - if (null != imageView) { - // Remove this as a global layout listener - ViewTreeObserver observer = imageView.getViewTreeObserver(); - if (null != observer && observer.isAlive()) { - observer.removeGlobalOnLayoutListener(this); - } - - // Remove the ImageView's reference to this - imageView.setOnTouchListener(null); - - // make sure a pending fling runnable won't be run - cancelFling(); - } - - if (null != mGestureDetector) { - mGestureDetector.setOnDoubleTapListener(null); - } - - // Clear listeners too - mMatrixChangeListener = null; - mPhotoTapListener = null; - mViewTapListener = null; - - // Finally, clear ImageView - mImageView = null; - } - - @Override - public RectF getDisplayRect() { - checkMatrixBounds(); - return getDisplayRect(getDrawMatrix()); - } - - @Override - public boolean setDisplayMatrix(Matrix finalMatrix) { - if (finalMatrix == null) { - throw new IllegalArgumentException("Matrix cannot be null"); - } - - ImageView imageView = getImageView(); - if (null == imageView) { - return false; - } - - if (null == imageView.getDrawable()) { - return false; - } - - mSuppMatrix.set(finalMatrix); - setImageViewMatrix(getDrawMatrix()); - checkMatrixBounds(); - - return true; - } - - public void setBaseRotation(final float degrees) { - mBaseRotation = degrees % 360; - update(); - setRotationBy(mBaseRotation); - checkAndDisplayMatrix(); - } - - /** - * @deprecated use {@link #setRotationTo(float)} - */ - @Override - public void setPhotoViewRotation(float degrees) { - mSuppMatrix.setRotate(degrees % 360); - checkAndDisplayMatrix(); - } - - @Override - public void setRotationTo(float degrees) { - mSuppMatrix.setRotate(degrees % 360); - checkAndDisplayMatrix(); - } - - @Override - public void setRotationBy(float degrees) { - mSuppMatrix.postRotate(degrees % 360); - checkAndDisplayMatrix(); - } - - public ImageView getImageView() { - ImageView imageView = null; - - if (null != mImageView) { - imageView = mImageView.get(); - } - - // If we don't have an ImageView, call cleanup() - if (null == imageView) { - cleanup(); - Logger.i("ImageView no longer exists. You should not use this PhotoViewAttacher any more."); - } - - return imageView; - } - - @Override - @Deprecated - public float getMinScale() { - return getMinimumScale(); - } - - @Override - @Deprecated - public void setMinScale(float minScale) { - setMinimumScale(minScale); - } - - @Override - public float getMinimumScale() { - return mMinScale; - } - - @Override - public void setMinimumScale(float minimumScale) { - checkZoomLevels(minimumScale, mMidScale, mMaxScale); - mMinScale = minimumScale; - } - - @Override - @Deprecated - public float getMidScale() { - return getMediumScale(); - } - - @Override - @Deprecated - public void setMidScale(float midScale) { - setMediumScale(midScale); - } - - @Override - public float getMediumScale() { - return mMidScale; - } - - @Override - public void setMediumScale(float mediumScale) { - checkZoomLevels(mMinScale, mediumScale, mMaxScale); - mMidScale = mediumScale; - } - - @Override - @Deprecated - public float getMaxScale() { - return getMaximumScale(); - } - - @Override - @Deprecated - public void setMaxScale(float maxScale) { - setMaximumScale(maxScale); - } - - @Override - public float getMaximumScale() { - return mMaxScale; - } - - @Override - public void setMaximumScale(float maximumScale) { - checkZoomLevels(mMinScale, mMidScale, maximumScale); - mMaxScale = maximumScale; - } - - @Override - public float getScale() { - return (float) Math.sqrt((float) Math.pow(getValue(mSuppMatrix, Matrix.MSCALE_X), 2) + (float) Math.pow(getValue(mSuppMatrix, Matrix.MSKEW_Y), 2)); - } - - @Override - public void setScale(float scale) { - setScale(scale, false); - } - - @Override - public ScaleType getScaleType() { - return mScaleType; - } - - @Override - public void setScaleType(ScaleType scaleType) { - if (isSupportedScaleType(scaleType) && scaleType != mScaleType) { - mScaleType = scaleType; - - // Finally update - update(); - } - } - - @Override - public void onDrag(float dx, float dy) { - if (mScaleDragDetector.isScaling()) { - return; // Do not drag if we are already scaling - } - - ImageView imageView = getImageView(); - mSuppMatrix.postTranslate(dx, dy); - checkAndDisplayMatrix(); - - /** - * Here we decide whether to let the ImageView's parent to start taking - * over the touch event. - * - * First we check whether this function is enabled. We never want the - * parent to take over if we're scaling. We then check the edge we're - * on, and the direction of the scroll (i.e. if we're pulling against - * the edge, aka 'overscrolling', let the parent take over). - */ - ViewParent parent = imageView.getParent(); - if (mAllowParentInterceptOnEdge && !mScaleDragDetector.isScaling() && !mBlockParentIntercept) { - if (mScrollEdge == EDGE_BOTH - || (mScrollEdge == EDGE_LEFT && dx >= 1f) - || (mScrollEdge == EDGE_RIGHT && dx <= -1f)) { - if (null != parent) { - parent.requestDisallowInterceptTouchEvent(false); - } - } - } else { - if (null != parent) { - parent.requestDisallowInterceptTouchEvent(true); - } - } - } - - @Override - public void onFling(float startX, float startY, float velocityX, - float velocityY) { - ImageView imageView = getImageView(); - mCurrentFlingRunnable = new FlingRunnable(imageView.getContext()); - mCurrentFlingRunnable.fling(getImageViewWidth(imageView), - getImageViewHeight(imageView), (int) velocityX, (int) velocityY); - imageView.post(mCurrentFlingRunnable); - } - - @Override - public void onGlobalLayout() { - ImageView imageView = getImageView(); - - if (null != imageView) { - if (mZoomEnabled) { - final int top = imageView.getTop(); - final int right = imageView.getRight(); - final int bottom = imageView.getBottom(); - final int left = imageView.getLeft(); - - /** - * We need to check whether the ImageView's bounds have changed. - * This would be easier if we targeted API 11+ as we could just use - * View.OnLayoutChangeListener. Instead we have to replicate the - * work, keeping track of the ImageView's bounds and then checking - * if the values change. - */ - if (top != mIvTop || bottom != mIvBottom || left != mIvLeft - || right != mIvRight) { - // Update our base matrix, as the bounds have changed - updateBaseMatrix(imageView.getDrawable()); - - // Update values as something has changed - mIvTop = top; - mIvRight = right; - mIvBottom = bottom; - mIvLeft = left; - } - } else { - updateBaseMatrix(imageView.getDrawable()); - } - } - } - - @Override - public void onScale(float scaleFactor, float focusX, float focusY) { - if ((getScale() < mMaxScale || scaleFactor < 1f) && (getScale() > mMinScale || scaleFactor > 1f)) { - if (null != mScaleChangeListener) { - mScaleChangeListener.onScaleChange(scaleFactor, focusX, focusY); - } - mSuppMatrix.postScale(scaleFactor, scaleFactor, focusX, focusY); - checkAndDisplayMatrix(); - } - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public boolean onTouch(View v, MotionEvent ev) { - boolean handled = false; - - if (mZoomEnabled && hasDrawable((ImageView) v)) { - ViewParent parent = v.getParent(); - switch (ev.getAction()) { - case ACTION_DOWN: - // First, disable the Parent from intercepting the touch - // event - if (null != parent) { - parent.requestDisallowInterceptTouchEvent(true); - } else { - Logger.i("onTouch getParent() returned null"); - } - - // If we're flinging, and the user presses down, cancel - // fling - cancelFling(); - break; - - case ACTION_CANCEL: - case ACTION_UP: - // If the user has zoomed less than min scale, zoom back - // to min scale - if (getScale() < mMinScale) { - RectF rect = getDisplayRect(); - if (null != rect) { - v.post(new AnimatedZoomRunnable(getScale(), mMinScale, - rect.centerX(), rect.centerY())); - handled = true; - } - } - break; - } - - // Try the Scale/Drag detector - if (null != mScaleDragDetector) { - boolean wasScaling = mScaleDragDetector.isScaling(); - boolean wasDragging = mScaleDragDetector.isDragging(); - - handled = mScaleDragDetector.onTouchEvent(ev); - - boolean didntScale = !wasScaling && !mScaleDragDetector.isScaling(); - boolean didntDrag = !wasDragging && !mScaleDragDetector.isDragging(); - - mBlockParentIntercept = didntScale && didntDrag; - } - - // Check to see if the user double tapped - if (null != mGestureDetector && mGestureDetector.onTouchEvent(ev)) { - handled = true; - } - - } - - return handled; - } - - @Override - public void setAllowParentInterceptOnEdge(boolean allow) { - mAllowParentInterceptOnEdge = allow; - } - - @Override - public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) { - checkZoomLevels(minimumScale, mediumScale, maximumScale); - mMinScale = minimumScale; - mMidScale = mediumScale; - mMaxScale = maximumScale; - } - - @Override - public void setOnLongClickListener(OnLongClickListener listener) { - mLongClickListener = listener; - } - - @Override - public void setOnMatrixChangeListener(OnMatrixChangedListener listener) { - mMatrixChangeListener = listener; - } - - @Override - @Deprecated - public OnPhotoTapListener getOnPhotoTapListener() { - return mPhotoTapListener; - } - - @Override - public void setOnPhotoTapListener(OnPhotoTapListener listener) { - mPhotoTapListener = listener; - } - - @Override - @Deprecated - public OnViewTapListener getOnViewTapListener() { - return mViewTapListener; - } - - @Override - public void setOnViewTapListener(OnViewTapListener listener) { - mViewTapListener = listener; - } - - @Override - public void setScale(float scale, boolean animate) { - ImageView imageView = getImageView(); - - if (null != imageView) { - setScale(scale, - (imageView.getRight()) / 2, - (imageView.getBottom()) / 2, - animate); - } - } - - @Override - public void setScale(float scale, float focalX, float focalY, - boolean animate) { - ImageView imageView = getImageView(); - - if (null != imageView) { - // Check to see if the scale is within bounds - if (scale < mMinScale || scale > mMaxScale) { - Logger.i("Scale must be within the range of minScale and maxScale"); - return; - } - - if (animate) { - imageView.post(new AnimatedZoomRunnable(getScale(), scale, - focalX, focalY)); - } else { - mSuppMatrix.setScale(scale, scale, focalX, focalY); - checkAndDisplayMatrix(); - } - } - } - - /** - * Set the zoom interpolator - * - * @param interpolator the zoom interpolator - */ - public void setZoomInterpolator(Interpolator interpolator) { - mInterpolator = interpolator; - } - - @Override - public void setZoomable(boolean zoomable) { - mZoomEnabled = zoomable; - update(); - } - - public void update() { - ImageView imageView = getImageView(); - - if (null != imageView) { - if (mZoomEnabled) { - // Make sure we using MATRIX Scale Type - setImageViewScaleTypeMatrix(imageView); - - // Update the base matrix using the current drawable - updateBaseMatrix(imageView.getDrawable()); - } else { - // Reset the Matrix... - resetMatrix(); - } - } - } - - /** - * Use {@link #getDisplayMatrix(Matrix)} - */ - @Deprecated - @Override - public Matrix getDisplayMatrix() { - return new Matrix(getDrawMatrix()); - } - - /** - * Like {@link #getDisplayMatrix()}, but allows the user to provide a matrix to copy the values into to reduce object allocation - * - * @param matrix target matrix to copy to - */ - @Override - public void getDisplayMatrix(Matrix matrix) { - matrix.set(getDrawMatrix()); - } - - /** - * Get the current support matrix - */ - public void getSuppMatrix(Matrix matrix) { - matrix.set(mSuppMatrix); - } - - @Deprecated - /** - * Method should be private - * Use {@link #getDisplayMatrix(Matrix)} - */ - public Matrix getDrawMatrix() { - mDrawMatrix.set(mBaseMatrix); - mDrawMatrix.postConcat(mSuppMatrix); - return mDrawMatrix; - } - - private void cancelFling() { - if (null != mCurrentFlingRunnable) { - mCurrentFlingRunnable.cancelFling(); - mCurrentFlingRunnable = null; - } - } - - /** - * Helper method that simply checks the Matrix, and then displays the result - */ - private void checkAndDisplayMatrix() { - if (checkMatrixBounds()) { - setImageViewMatrix(getDrawMatrix()); - } - } - - private void checkImageViewScaleType() { - ImageView imageView = getImageView(); - - /** - * PhotoView's getScaleType() will just divert to this.getScaleType() so - * only call if we're not attached to a PhotoView. - */ - if (null != imageView && !(imageView instanceof IPhotoView)) { - if (!ScaleType.MATRIX.equals(imageView.getScaleType())) { - throw new IllegalStateException( - "The ImageView's ScaleType has been changed since attaching a PhotoViewAttacher. You should call setScaleType on the PhotoViewAttacher instead of on the ImageView"); - } - } - } - - private boolean checkMatrixBounds() { - final ImageView imageView = getImageView(); - if (null == imageView) { - return false; - } - - final RectF rect = getDisplayRect(getDrawMatrix()); - if (null == rect) { - return false; - } - - final float height = rect.height(), width = rect.width(); - float deltaX = 0, deltaY = 0; - - final int viewHeight = getImageViewHeight(imageView); - if (height <= viewHeight) { - switch (mScaleType) { - case FIT_START: - deltaY = -rect.top; - break; - case FIT_END: - deltaY = viewHeight - height - rect.top; - break; - default: - deltaY = (viewHeight - height) / 2 - rect.top; - break; - } - } else if (rect.top > 0) { - deltaY = -rect.top; - } else if (rect.bottom < viewHeight) { - deltaY = viewHeight - rect.bottom; - } - - final int viewWidth = getImageViewWidth(imageView); - if (width <= viewWidth) { - switch (mScaleType) { - case FIT_START: - deltaX = -rect.left; - break; - case FIT_END: - deltaX = viewWidth - width - rect.left; - break; - default: - deltaX = (viewWidth - width) / 2 - rect.left; - break; - } - mScrollEdge = EDGE_BOTH; - } else if (rect.left > 0) { - mScrollEdge = EDGE_LEFT; - deltaX = -rect.left; - } else if (rect.right < viewWidth) { - deltaX = viewWidth - rect.right; - mScrollEdge = EDGE_RIGHT; - } else { - mScrollEdge = EDGE_NONE; - } - - // Finally actually translate the matrix - mSuppMatrix.postTranslate(deltaX, deltaY); - return true; - } - - /** - * Helper method that maps the supplied Matrix to the current Drawable - * - * @param matrix - Matrix to map Drawable against - * @return RectF - Displayed Rectangle - */ - private RectF getDisplayRect(Matrix matrix) { - ImageView imageView = getImageView(); - - if (null != imageView) { - Drawable d = imageView.getDrawable(); - if (null != d) { - mDisplayRect.set(0, 0, d.getIntrinsicWidth(), - d.getIntrinsicHeight()); - matrix.mapRect(mDisplayRect); - return mDisplayRect; - } - } - return null; - } - - public Bitmap getVisibleRectangleBitmap() { - ImageView imageView = getImageView(); - return imageView == null ? null : imageView.getDrawingCache(); - } - - @Override - public void setZoomTransitionDuration(int milliseconds) { - if (milliseconds < 0) - milliseconds = DEFAULT_ZOOM_DURATION; - this.ZOOM_DURATION = milliseconds; - } - - @Override - public IPhotoView getIPhotoViewImplementation() { - return this; - } - - /** - * Helper method that 'unpacks' a Matrix and returns the required value - * - * @param matrix - Matrix to unpack - * @param whichValue - Which value from Matrix.M* to return - * @return float - returned value - */ - private float getValue(Matrix matrix, int whichValue) { - matrix.getValues(mMatrixValues); - return mMatrixValues[whichValue]; - } - - /** - * Resets the Matrix back to FIT_CENTER, and then displays it.s - */ - private void resetMatrix() { - mSuppMatrix.reset(); - setRotationBy(mBaseRotation); - setImageViewMatrix(getDrawMatrix()); - checkMatrixBounds(); - } - - private void setImageViewMatrix(Matrix matrix) { - ImageView imageView = getImageView(); - if (null != imageView) { - - checkImageViewScaleType(); - imageView.setImageMatrix(matrix); - - // Call MatrixChangedListener if needed - if (null != mMatrixChangeListener) { - RectF displayRect = getDisplayRect(matrix); - if (null != displayRect) { - mMatrixChangeListener.onMatrixChanged(displayRect); - } - } - } - } - - /** - * Calculate Matrix for FIT_CENTER - * - * @param d - Drawable being displayed - */ - private void updateBaseMatrix(Drawable d) { - ImageView imageView = getImageView(); - if (null == imageView || null == d) { - return; - } - - final float viewWidth = getImageViewWidth(imageView); - final float viewHeight = getImageViewHeight(imageView); - final int drawableWidth = d.getIntrinsicWidth(); - final int drawableHeight = d.getIntrinsicHeight(); - - mBaseMatrix.reset(); - - final float widthScale = viewWidth / drawableWidth; - final float heightScale = viewHeight / drawableHeight; - - if (mScaleType == ScaleType.CENTER) { - mBaseMatrix.postTranslate((viewWidth - drawableWidth) / 2F, - (viewHeight - drawableHeight) / 2F); - - } else if (mScaleType == ScaleType.CENTER_CROP) { - float scale = Math.max(widthScale, heightScale); - mBaseMatrix.postScale(scale, scale); - mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F, - (viewHeight - drawableHeight * scale) / 2F); - - } else if (mScaleType == ScaleType.CENTER_INSIDE) { - float scale = Math.min(1.0f, Math.min(widthScale, heightScale)); - mBaseMatrix.postScale(scale, scale); - mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F, - (viewHeight - drawableHeight * scale) / 2F); - - } else { - RectF mTempSrc = new RectF(0, 0, drawableWidth, drawableHeight); - RectF mTempDst = new RectF(0, 0, viewWidth, viewHeight); - - if ((int) mBaseRotation % 180 != 0) { - mTempSrc = new RectF(0, 0, drawableHeight, drawableWidth); - } - - switch (mScaleType) { - case FIT_CENTER: - mBaseMatrix - .setRectToRect(mTempSrc, mTempDst, ScaleToFit.CENTER); - break; - - case FIT_START: - mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.START); - break; - - case FIT_END: - mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.END); - break; - - case FIT_XY: - mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.FILL); - break; - - default: - break; - } - } - - resetMatrix(); - } - - private int getImageViewWidth(ImageView imageView) { - if (null == imageView) - return 0; - return imageView.getWidth() - imageView.getPaddingLeft() - imageView.getPaddingRight(); - } - - private int getImageViewHeight(ImageView imageView) { - if (null == imageView) - return 0; - return imageView.getHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom(); - } - - /** - * Interface definition for a callback to be invoked when the internal Matrix has changed for - * this View. - * - * @author Chris Banes - */ - public interface OnMatrixChangedListener { - /** - * Callback for when the Matrix displaying the Drawable has changed. This could be because - * the View's bounds have changed, or the user has zoomed. - * - * @param rect - Rectangle displaying the Drawable's new bounds. - */ - void onMatrixChanged(RectF rect); - } - - /** - * Interface definition for callback to be invoked when attached ImageView scale changes - * - * @author Marek Sebera - */ - public interface OnScaleChangeListener { - /** - * Callback for when the scale changes - * - * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in) - * @param focusX focal point X position - * @param focusY focal point Y position - */ - void onScaleChange(float scaleFactor, float focusX, float focusY); - } - - /** - * Interface definition for a callback to be invoked when the Photo is tapped with a single - * tap. - * - * @author Chris Banes - */ - public interface OnPhotoTapListener { - - /** - * A callback to receive where the user taps on a photo. You will only receive a callback if - * the user taps on the actual photo, tapping on 'whitespace' will be ignored. - * - * @param view - View the user tapped. - * @param x - where the user tapped from the of the Drawable, as percentage of the - * Drawable width. - * @param y - where the user tapped from the top of the Drawable, as percentage of the - * Drawable height. - */ - void onPhotoTap(View view, float x, float y); - - /** - * A simple callback where out of photo happened; - */ - void onOutsidePhotoTap(); - } - - /** - * Interface definition for a callback to be invoked when the ImageView is tapped with a single - * tap. - * - * @author Chris Banes - */ - public interface OnViewTapListener { - - /** - * A callback to receive where the user taps on a ImageView. You will receive a callback if - * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. - * - * @param view - View the user tapped. - * @param x - where the user tapped from the left of the View. - * @param y - where the user tapped from the top of the View. - */ - void onViewTap(View view, float x, float y); - } - - /** - * Interface definition for a callback to be invoked when the ImageView is fling with a single - * touch - * - * @author tonyjs - */ - public interface OnSingleFlingListener { - - /** - * A callback to receive where the user flings on a ImageView. You will receive a callback if - * the user flings anywhere on the view. - * - * @param e1 - MotionEvent the user first touch. - * @param e2 - MotionEvent the user last touch. - * @param velocityX - distance of user's horizontal fling. - * @param velocityY - distance of user's vertical fling. - */ - boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); - } - - private class AnimatedZoomRunnable implements Runnable { - - private final float mFocalX, mFocalY; - private final long mStartTime; - private final float mZoomStart, mZoomEnd; - - public AnimatedZoomRunnable(final float currentZoom, final float targetZoom, - final float focalX, final float focalY) { - mFocalX = focalX; - mFocalY = focalY; - mStartTime = System.currentTimeMillis(); - mZoomStart = currentZoom; - mZoomEnd = targetZoom; - } - - @Override - public void run() { - ImageView imageView = getImageView(); - if (imageView == null) { - return; - } - - float t = interpolate(); - float scale = mZoomStart + t * (mZoomEnd - mZoomStart); - float deltaScale = scale / getScale(); - - onScale(deltaScale, mFocalX, mFocalY); - - // We haven't hit our target scale yet, so post ourselves again - if (t < 1f) { - Compat.postOnAnimation(imageView, this); - } - } - - private float interpolate() { - float t = 1f * (System.currentTimeMillis() - mStartTime) / ZOOM_DURATION; - t = Math.min(1f, t); - t = mInterpolator.getInterpolation(t); - return t; - } - } - - private class FlingRunnable implements Runnable { - - private final ScrollerProxy mScroller; - private int mCurrentX, mCurrentY; - - public FlingRunnable(Context context) { - mScroller = ScrollerProxy.getScroller(context); - } - - public void cancelFling() { - mScroller.forceFinished(true); - } - - public void fling(int viewWidth, int viewHeight, int velocityX, - int velocityY) { - final RectF rect = getDisplayRect(); - if (null == rect) { - return; - } - - final int startX = Math.round(-rect.left); - final int minX, maxX, minY, maxY; - - if (viewWidth < rect.width()) { - minX = 0; - maxX = Math.round(rect.width() - viewWidth); - } else { - minX = maxX = startX; - } - - final int startY = Math.round(-rect.top); - if (viewHeight < rect.height()) { - minY = 0; - maxY = Math.round(rect.height() - viewHeight); - } else { - minY = maxY = startY; - } - - mCurrentX = startX; - mCurrentY = startY; - - // If we actually can move, fling the scroller - if (startX != maxX || startY != maxY) { - mScroller.fling(startX, startY, velocityX, velocityY, minX, - maxX, minY, maxY, 0, 0); - } - } - - @Override - public void run() { - if (mScroller.isFinished()) { - return; // remaining post that should not be handled - } - - ImageView imageView = getImageView(); - if (null != imageView && mScroller.computeScrollOffset()) { - - final int newX = mScroller.getCurrX(); - final int newY = mScroller.getCurrY(); - - mSuppMatrix.postTranslate(mCurrentX - newX, mCurrentY - newY); - setImageViewMatrix(getDrawMatrix()); - - mCurrentX = newX; - mCurrentY = newY; - - // Post On animation - Compat.postOnAnimation(imageView, this); - } - } - } -} diff --git a/library/src/main/java/uk/co/senab/photoview/gestures/CupcakeGestureDetector.java b/library/src/main/java/uk/co/senab/photoview/gestures/CupcakeGestureDetector.java deleted file mode 100755 index a526bb77..00000000 --- a/library/src/main/java/uk/co/senab/photoview/gestures/CupcakeGestureDetector.java +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.gestures; - -import android.content.Context; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.ViewConfiguration; - -import cn.finalteam.rxgalleryfinal.utils.Logger; - -public class CupcakeGestureDetector implements GestureDetector { - - private static final String LOG_TAG = "CupcakeGestureDetector"; - final float mTouchSlop; - final float mMinimumVelocity; - protected OnGestureListener mListener; - float mLastTouchX; - float mLastTouchY; - private VelocityTracker mVelocityTracker; - private boolean mIsDragging; - - public CupcakeGestureDetector(Context context) { - final ViewConfiguration configuration = ViewConfiguration - .get(context); - mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); - mTouchSlop = configuration.getScaledTouchSlop(); - } - - @Override - public void setOnGestureListener(OnGestureListener listener) { - this.mListener = listener; - } - - float getActiveX(MotionEvent ev) { - return ev.getX(); - } - - float getActiveY(MotionEvent ev) { - return ev.getY(); - } - - @Override - public boolean isScaling() { - return false; - } - - @Override - public boolean isDragging() { - return mIsDragging; - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: { - mVelocityTracker = VelocityTracker.obtain(); - if (null != mVelocityTracker) { - mVelocityTracker.addMovement(ev); - } else { - Logger.i("Velocity tracker is null"); - } - - mLastTouchX = getActiveX(ev); - mLastTouchY = getActiveY(ev); - mIsDragging = false; - break; - } - - case MotionEvent.ACTION_MOVE: { - final float x = getActiveX(ev); - final float y = getActiveY(ev); - final float dx = x - mLastTouchX, dy = y - mLastTouchY; - - if (!mIsDragging) { - // Use Pythagoras to see if drag length is larger than - // touch slop - mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop; - } - - if (mIsDragging) { - mListener.onDrag(dx, dy); - mLastTouchX = x; - mLastTouchY = y; - - if (null != mVelocityTracker) { - mVelocityTracker.addMovement(ev); - } - } - break; - } - - case MotionEvent.ACTION_CANCEL: { - // Recycle Velocity Tracker - if (null != mVelocityTracker) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - break; - } - - case MotionEvent.ACTION_UP: { - if (mIsDragging) { - if (null != mVelocityTracker) { - mLastTouchX = getActiveX(ev); - mLastTouchY = getActiveY(ev); - - // Compute velocity within the last 1000ms - mVelocityTracker.addMovement(ev); - mVelocityTracker.computeCurrentVelocity(1000); - - final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker - .getYVelocity(); - - // If the velocity is greater than minVelocity, call - // listener - if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) { - mListener.onFling(mLastTouchX, mLastTouchY, -vX, - -vY); - } - } - } - - // Recycle Velocity Tracker - if (null != mVelocityTracker) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - break; - } - } - - return true; - } -} diff --git a/library/src/main/java/uk/co/senab/photoview/gestures/EclairGestureDetector.java b/library/src/main/java/uk/co/senab/photoview/gestures/EclairGestureDetector.java deleted file mode 100755 index c467e1c8..00000000 --- a/library/src/main/java/uk/co/senab/photoview/gestures/EclairGestureDetector.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.gestures; - -import android.annotation.TargetApi; -import android.content.Context; -import android.view.MotionEvent; - -import uk.co.senab.photoview.Compat; - -@TargetApi(5) -public class EclairGestureDetector extends CupcakeGestureDetector { - - private static final int INVALID_POINTER_ID = -1; - private int mActivePointerId = INVALID_POINTER_ID; - private int mActivePointerIndex = 0; - - public EclairGestureDetector(Context context) { - super(context); - } - - @Override - float getActiveX(MotionEvent ev) { - try { - return ev.getX(mActivePointerIndex); - } catch (Exception e) { - return ev.getX(); - } - } - - @Override - float getActiveY(MotionEvent ev) { - try { - return ev.getY(mActivePointerIndex); - } catch (Exception e) { - return ev.getY(); - } - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - final int action = ev.getAction(); - switch (action & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - mActivePointerId = ev.getPointerId(0); - break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - mActivePointerId = INVALID_POINTER_ID; - break; - case MotionEvent.ACTION_POINTER_UP: - // Ignore deprecation, ACTION_POINTER_ID_MASK and - // ACTION_POINTER_ID_SHIFT has same value and are deprecated - // You can have either deprecation or lint target api warning - final int pointerIndex = Compat.getPointerIndex(ev.getAction()); - final int pointerId = ev.getPointerId(pointerIndex); - if (pointerId == mActivePointerId) { - // This was our active pointer going up. Choose a new - // active pointer and adjust accordingly. - final int newPointerIndex = pointerIndex == 0 ? 1 : 0; - mActivePointerId = ev.getPointerId(newPointerIndex); - mLastTouchX = ev.getX(newPointerIndex); - mLastTouchY = ev.getY(newPointerIndex); - } - break; - } - - mActivePointerIndex = ev - .findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId - : 0); - try { - return super.onTouchEvent(ev); - } catch (IllegalArgumentException e) { - // Fix for support lib bug, happening when onDestroy is - return true; - } - } -} diff --git a/library/src/main/java/uk/co/senab/photoview/gestures/FroyoGestureDetector.java b/library/src/main/java/uk/co/senab/photoview/gestures/FroyoGestureDetector.java deleted file mode 100755 index 7343e3c0..00000000 --- a/library/src/main/java/uk/co/senab/photoview/gestures/FroyoGestureDetector.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.gestures; - -import android.annotation.TargetApi; -import android.content.Context; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; - -@TargetApi(8) -public class FroyoGestureDetector extends EclairGestureDetector { - - protected final ScaleGestureDetector mDetector; - - public FroyoGestureDetector(Context context) { - super(context); - ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() { - - @Override - public boolean onScale(ScaleGestureDetector detector) { - float scaleFactor = detector.getScaleFactor(); - - if (Float.isNaN(scaleFactor) || Float.isInfinite(scaleFactor)) - return false; - - mListener.onScale(scaleFactor, - detector.getFocusX(), detector.getFocusY()); - return true; - } - - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - return true; - } - - @Override - public void onScaleEnd(ScaleGestureDetector detector) { - // NO-OP - } - }; - mDetector = new ScaleGestureDetector(context, mScaleListener); - } - - @Override - public boolean isScaling() { - return mDetector.isInProgress(); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - try { - mDetector.onTouchEvent(ev); - return super.onTouchEvent(ev); - } catch (IllegalArgumentException e) { - // Fix for support lib bug, happening when onDestroy is - return true; - } - } -} diff --git a/library/src/main/java/uk/co/senab/photoview/gestures/GestureDetector.java b/library/src/main/java/uk/co/senab/photoview/gestures/GestureDetector.java deleted file mode 100755 index 3c9177ec..00000000 --- a/library/src/main/java/uk/co/senab/photoview/gestures/GestureDetector.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.gestures; - -import android.view.MotionEvent; - -public interface GestureDetector { - - boolean onTouchEvent(MotionEvent ev); - - boolean isScaling(); - - boolean isDragging(); - - void setOnGestureListener(OnGestureListener listener); - -} diff --git a/library/src/main/java/uk/co/senab/photoview/gestures/OnGestureListener.java b/library/src/main/java/uk/co/senab/photoview/gestures/OnGestureListener.java deleted file mode 100755 index 4c124d1e..00000000 --- a/library/src/main/java/uk/co/senab/photoview/gestures/OnGestureListener.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.gestures; - -public interface OnGestureListener { - - void onDrag(float dx, float dy); - - void onFling(float startX, float startY, float velocityX, - float velocityY); - - void onScale(float scaleFactor, float focusX, float focusY); - -} \ No newline at end of file diff --git a/library/src/main/java/uk/co/senab/photoview/gestures/VersionedGestureDetector.java b/library/src/main/java/uk/co/senab/photoview/gestures/VersionedGestureDetector.java deleted file mode 100755 index c1550ce3..00000000 --- a/library/src/main/java/uk/co/senab/photoview/gestures/VersionedGestureDetector.java +++ /dev/null @@ -1,42 +0,0 @@ -package uk.co.senab.photoview.gestures; - -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ - -import android.content.Context; -import android.os.Build; - -public final class VersionedGestureDetector { - - public static GestureDetector newInstance(Context context, - OnGestureListener listener) { - final int sdkVersion = Build.VERSION.SDK_INT; - GestureDetector detector; - - if (sdkVersion < Build.VERSION_CODES.ECLAIR) { - detector = new CupcakeGestureDetector(context); - } else if (sdkVersion < Build.VERSION_CODES.FROYO) { - detector = new EclairGestureDetector(context); - } else { - detector = new FroyoGestureDetector(context); - } - - detector.setOnGestureListener(listener); - - return detector; - } - -} \ No newline at end of file diff --git a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/GingerScroller.java b/library/src/main/java/uk/co/senab/photoview/scrollerproxy/GingerScroller.java deleted file mode 100755 index c58cdb96..00000000 --- a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/GingerScroller.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.scrollerproxy; - -import android.annotation.TargetApi; -import android.content.Context; -import android.widget.OverScroller; - -@TargetApi(9) -public class GingerScroller extends ScrollerProxy { - - protected final OverScroller mScroller; - private boolean mFirstScroll = false; - - public GingerScroller(Context context) { - mScroller = new OverScroller(context); - } - - @Override - public boolean computeScrollOffset() { - // Workaround for first scroll returning 0 for the direction of the edge it hits. - // Simply recompute values. - if (mFirstScroll) { - mScroller.computeScrollOffset(); - mFirstScroll = false; - } - return mScroller.computeScrollOffset(); - } - - @Override - public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, - int overX, int overY) { - mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, overX, overY); - } - - @Override - public void forceFinished(boolean finished) { - mScroller.forceFinished(finished); - } - - @Override - public boolean isFinished() { - return mScroller.isFinished(); - } - - @Override - public int getCurrX() { - return mScroller.getCurrX(); - } - - @Override - public int getCurrY() { - return mScroller.getCurrY(); - } -} \ No newline at end of file diff --git a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/IcsScroller.java b/library/src/main/java/uk/co/senab/photoview/scrollerproxy/IcsScroller.java deleted file mode 100755 index 10f9eab8..00000000 --- a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/IcsScroller.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.scrollerproxy; - -import android.annotation.TargetApi; -import android.content.Context; - -@TargetApi(14) -public class IcsScroller extends GingerScroller { - - public IcsScroller(Context context) { - super(context); - } - - @Override - public boolean computeScrollOffset() { - return mScroller.computeScrollOffset(); - } - -} diff --git a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/PreGingerScroller.java b/library/src/main/java/uk/co/senab/photoview/scrollerproxy/PreGingerScroller.java deleted file mode 100755 index 2cd91b3f..00000000 --- a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/PreGingerScroller.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.scrollerproxy; - -import android.content.Context; -import android.widget.Scroller; - -public class PreGingerScroller extends ScrollerProxy { - - private final Scroller mScroller; - - public PreGingerScroller(Context context) { - mScroller = new Scroller(context); - } - - @Override - public boolean computeScrollOffset() { - return mScroller.computeScrollOffset(); - } - - @Override - public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, - int overX, int overY) { - mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); - } - - @Override - public void forceFinished(boolean finished) { - mScroller.forceFinished(finished); - } - - public boolean isFinished() { - return mScroller.isFinished(); - } - - @Override - public int getCurrX() { - return mScroller.getCurrX(); - } - - @Override - public int getCurrY() { - return mScroller.getCurrY(); - } -} \ No newline at end of file diff --git a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/ScrollerProxy.java b/library/src/main/java/uk/co/senab/photoview/scrollerproxy/ScrollerProxy.java deleted file mode 100755 index ce39ef19..00000000 --- a/library/src/main/java/uk/co/senab/photoview/scrollerproxy/ScrollerProxy.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package uk.co.senab.photoview.scrollerproxy; - -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; - -public abstract class ScrollerProxy { - - public static ScrollerProxy getScroller(Context context) { - if (VERSION.SDK_INT < VERSION_CODES.GINGERBREAD) { - return new PreGingerScroller(context); - } else if (VERSION.SDK_INT < VERSION_CODES.ICE_CREAM_SANDWICH) { - return new GingerScroller(context); - } else { - return new IcsScroller(context); - } - } - - public abstract boolean computeScrollOffset(); - - public abstract void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, - int maxY, int overX, int overY); - - public abstract void forceFinished(boolean finished); - - public abstract boolean isFinished(); - - public abstract int getCurrX(); - - public abstract int getCurrY(); - - -} diff --git a/library/src/main/res/layout/gallery_media_image_preview_item.xml b/library/src/main/res/layout/gallery_media_image_preview_item.xml index f3c093df..bb19dc00 100644 --- a/library/src/main/res/layout/gallery_media_image_preview_item.xml +++ b/library/src/main/res/layout/gallery_media_image_preview_item.xml @@ -1,5 +1,5 @@ - \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 7a00f443..71051f4d 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,16 +1,13 @@ apply plugin: 'com.android.application' -apply plugin: 'com.getkeepsafe.dexcount' android { - compileSdkVersion 24 - buildToolsVersion '25.0.3' - // buildToolsVersion '24' + compileSdkVersion 27 + buildToolsVersion '27.0.3' defaultConfig { applicationId "cn.finalteam.rxgalleryfinal.sample" minSdkVersion 14 - targetSdkVersion 25 - // targetSdkVersion 24 + targetSdkVersion 27 versionCode 1 versionName "1.0" } @@ -34,12 +31,15 @@ android { dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' - compile 'com.squareup.picasso:picasso:2.5.2' - compile 'com.facebook.fresco:fresco:1.3.0' - compile 'com.facebook.fresco:animated-gif:1.3.0' - compile 'com.github.bumptech.glide:glide:3.7.0' - compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' - debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1' + implementation 'com.android.support:recyclerview-v7:27.1.1' + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support:exifinterface:27.1.1' + implementation 'com.squareup.picasso:picasso:2.5.2' + implementation 'com.facebook.fresco:fresco:1.9.0' + implementation 'com.facebook.fresco:animated-gif:1.9.0' + implementation 'com.github.bumptech.glide:glide:3.7.0' + implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' + debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' compile project(':library') diff --git a/sample/src/main/java/cn/finalteam/rxgalleryfinal/sample/MainActivity.java b/sample/src/main/java/cn/finalteam/rxgalleryfinal/sample/MainActivity.java index b5089f7c..1dadeca4 100644 --- a/sample/src/main/java/cn/finalteam/rxgalleryfinal/sample/MainActivity.java +++ b/sample/src/main/java/cn/finalteam/rxgalleryfinal/sample/MainActivity.java @@ -1,3 +1,4 @@ + package cn.finalteam.rxgalleryfinal.sample; import android.app.Activity; @@ -197,7 +198,8 @@ private void openImageSelect() { } else if (mRbMutiIMG.isChecked()) { openImageSelectMultiMethod(1); } else { - if (PermissionCheckUtils.checkCameraPermission(this, "", MediaActivity.REQUEST_CAMERA_ACCESS_PERMISSION)) { + if (PermissionCheckUtils.checkCameraPermission(this, "", MediaActivity.REQUEST_CAMERA_ACCESS_PERMISSION) + && PermissionCheckUtils.checkWriteExternalPermission(this, "", MediaActivity.REQUEST_CAMERA_ACCESS_PERMISSION)) { RxGalleryFinalApi.openZKCamera(MainActivity.this); } }