/*******************************************************************************
* 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.Matrix;
import android.graphics.Matrix.ScaleToFit;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import java.lang.ref.WeakReference;
public class PhotoViewAttacher implements IPhotoView, View.OnTouchListener, VersionedGestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener, ViewTreeObserver.OnGlobalLayoutListener {
static final String LOG_TAG = "PhotoViewAttacher";
// let debug flag be dynamic, but still Proguard can be used to remove from release builds
static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
static final int EDGE_NONE = -1;
static final int EDGE_LEFT = 0;
static final int EDGE_RIGHT = 1;
static final int EDGE_BOTH = 2;
public static final float DEFAULT_MAX_SCALE = 3.0f;
public static final float DEFAULT_MID_SCALE = 1.75f;
public static final float DEFAULT_MIN_SCALE = 1.0f;
private float mMinScale = DEFAULT_MIN_SCALE;
private float mMidScale = DEFAULT_MID_SCALE;
private float mMaxScale = DEFAULT_MAX_SCALE;
private boolean mAllowParentInterceptOnEdge = true;
private static void checkZoomLevels(float minZoom, float midZoom, float maxZoom) {
if (minZoom >= midZoom) {
throw new IllegalArgumentException("MinZoom should be less than MidZoom");
} else if (midZoom >= maxZoom) {
throw new IllegalArgumentException("MidZoom should be less than MaxZoom");
}
}
/**
* @return true if the ImageView exists, and it's Drawable existss
*/
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) {
if (null != imageView) {
if (imageView instanceof PhotoView) {
/**
* PhotoView sets it's own ScaleType to Matrix, then diverts all
* calls setScaleType to this.setScaleType. Basically we don't
* need to do anything here
*/
} else {
imageView.setScaleType(ScaleType.MATRIX);
}
}
}
private WeakReference<ImageView> mImageView;
private ViewTreeObserver mViewTreeObserver;
// Gesture Detectors
private GestureDetector mGestureDetector;
private VersionedGestureDetector mScaleDragDetector;
// 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];
// Listeners
private OnMatrixChangedListener mMatrixChangeListener;
private OnPhotoTapListener mPhotoTapListener;
private OnViewTapListener mViewTapListener;
private OnLongClickListener mLongClickListener;
private int mIvTop, mIvRight, mIvBottom, mIvLeft;
private FlingRunnable mCurrentFlingRunnable;
private int mScrollEdge = EDGE_BOTH;
private boolean mZoomEnabled;
private ScaleType mScaleType = ScaleType.FIT_CENTER;
public PhotoViewAttacher(ImageView imageView) {
mImageView = new WeakReference<ImageView>(imageView);
imageView.setOnTouchListener(this);
mViewTreeObserver = imageView.getViewTreeObserver();
mViewTreeObserver.addOnGlobalLayoutListener(this);
// Make sure we using MATRIX Scale Type
setImageViewScaleTypeMatrix(imageView);
if (!imageView.isInEditMode()) {
// 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(mImageView.get());
}
}});
mGestureDetector.setOnDoubleTapListener(this);
// Finally, update the UI so that we're zoomable
setZoomable(true);
}
}
@Override
public final 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 android.view.View#onDetachedFromWindow()} or from {@link android.app.Activity#onDestroy()}.
* This is automatically called if you are using {@link uk.co.senab.photoview.PhotoView}.
*/
@SuppressWarnings("deprecation")
public final void cleanup() {
if (null != mImageView) {
mImageView.get().getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
mViewTreeObserver = null;
// Clear listeners too
mMatrixChangeListener = null;
mPhotoTapListener = null;
mViewTapListener = null;
// Finally, clear ImageView
mImageView = null;
}
@Override
public final RectF getDisplayRect() {
checkMatrixBounds();
return getDisplayRect(getDisplayMatrix());
}
public final ImageView getImageView() {
ImageView imageView = null;
if (null != mImageView) {
imageView = mImageView.get();
}
// If we don't have an ImageView, call cleanup()
if (null == imageView) {
cleanup();
throw new IllegalStateException(
"ImageView no longer exists. You should not use this PhotoViewAttacher any more.");
}
return imageView;
}
@Override
public float getMinScale() {
return mMinScale;
}
@Override
public float getMidScale() {
return mMidScale;
}
@Override
public float getMaxScale() {
return mMaxScale;
}
@Override
public final float getScale() {
return getValue(mSuppMatrix, Matrix.MSCALE_X);
}
@Override
public final ScaleType getScaleType() {
return mScaleType;
}
public final boolean onDoubleTap(MotionEvent ev) {
try {
float scale = getScale();
float x = ev.getX();
float y = ev.getY();
if (scale < mMidScale) {
zoomTo(mMidScale, x, y);
} else if (scale >= mMidScale && scale < mMaxScale) {
zoomTo(mMaxScale, x, y);
} else {
zoomTo(mMinScale, x, y);
}
} catch (ArrayIndexOutOfBoundsException e) {
// Can sometimes happen when getX() and getY() is called
}
return true;
}
public final boolean onDoubleTapEvent(MotionEvent e) {
// Wait for the confirmed onDoubleTap() instead
return false;
}
public final void onDrag(float dx, float dy) {
if (DEBUG) {
Log.d(LOG_TAG, String.format("onDrag: dx: %.2f. dy: %.2f", dx, dy));
}
ImageView imageView = getImageView();
if (null != imageView && hasDrawable(imageView)) {
mSuppMatrix.postTranslate(dx, dy);
checkAndDisplayMatrix();
/**
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Android+相册+支持图片缩放滑动+边界回弹+双击放大.zip (78个子文件)
sample
.project 852B
project.properties 602B
lint.xml 53B
src
uk
co
senab
photoview
ScrollerProxy.java 3KB
SDK16.java 982B
Compat.java 450B
PhotoView.java 4KB
VersionedGestureDetector.java 7KB
PhotoViewAttacher.java 25KB
sample
LauncherActivity.java 2KB
HackyViewPager.java 928B
SimpleSampleActivity.java 4KB
ViewPagerActivity.java 2KB
IPhotoView.java 5KB
AndroidManifest.xml 836B
res
drawable-ldpi
ic_launcher.png 3KB
drawable-hdpi
ic_launcher.png 7KB
a2.jpg 42KB
a1.jpg 70KB
a3.jpg 20KB
menu
main_menu.xml 1KB
drawable-nodpi
wallpaper.jpg 92KB
drawable-mdpi
ic_launcher.png 4KB
layout
activity_main.xml 691B
drawable-xhdpi
ic_launcher.png 11KB
values
strings.xml 677B
LICENSE 11KB
assets
gen
uk
co
senab
photoview
sample
BuildConfig.java 170B
R.java 2KB
libs
android-support-v4.jar 377KB
pom.xml 1KB
.classpath 364B
bin
resources.ap_ 256KB
LauncherActivity.apk 418KB
classes
uk
co
senab
photoview
VersionedGestureDetector.class 2KB
VersionedGestureDetector$OnGestureListener.class 352B
VersionedGestureDetector$CupcakeDetector.class 3KB
PhotoViewAttacher.class 18KB
PhotoViewAttacher$1.class 1KB
PhotoViewAttacher$OnMatrixChangedListener.class 319B
IPhotoView.class 1KB
PhotoView.class 5KB
VersionedGestureDetector$FroyoDetector.class 2KB
PhotoViewAttacher$OnViewTapListener.class 298B
PhotoViewAttacher$OnPhotoTapListener.class 301B
ScrollerProxy$PreGingerScroller.class 1KB
sample
R$layout.class 433B
BuildConfig.class 365B
R$drawable.class 548B
R$attr.class 370B
ViewPagerActivity$SamplePagerAdapter.class 2KB
SimpleSampleActivity$PhotoTapListener.class 2KB
ViewPagerActivity.class 994B
SimpleSampleActivity$MatrixChangeListener.class 1KB
R$id.class 822B
LauncherActivity.class 2KB
R.class 657B
R$string.class 816B
R$menu.class 423B
HackyViewPager.class 774B
SimpleSampleActivity.class 4KB
Compat.class 848B
PhotoViewAttacher$AnimatedZoomRunnable.class 2KB
VersionedGestureDetector$EclairDetector.class 2KB
PhotoViewAttacher$FlingRunnable.class 3KB
ScrollerProxy.class 1016B
ScrollerProxy$GingerScroller.class 1KB
SDK16.class 631B
VersionedGestureDetector$FroyoDetector$1.class 2KB
AndroidManifest.xml 836B
dexedLibs
android-support-v4-6c7ad30de8a77d5aaa4bb0cfe40e85dc.jar 146KB
android-support-v4-acb6dcede788c5219c3cbb7aacf14c8b.jar 146KB
jarlist.cache 119B
res
drawable-ldpi
ic_launcher.png 3KB
drawable-hdpi
ic_launcher.png 7KB
drawable-mdpi
ic_launcher.png 4KB
drawable-xhdpi
ic_launcher.png 11KB
classes.dex 467KB
共 78 条
- 1
资源评论
- violet198906102015-02-27非常好用,谢谢楼主分享
- waylen:)2015-01-09解决了我的项目问题
- jiangheshuilc2015-02-26非常实用,得到了想要的效果
- fanshanren2015-06-05非常实用,已收藏
shangxinlei88
- 粉丝: 11
- 资源: 13
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功