/*******************************************************************************
* 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();
/**
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
sample.zip (78个子文件)
sample
.project 852B
pom.xml 1KB
bin
LauncherActivity.apk 418KB
AndroidManifest.xml 836B
jarlist.cache 119B
dexedLibs
android-support-v4-6c7ad30de8a77d5aaa4bb0cfe40e85dc.jar 146KB
android-support-v4-acb6dcede788c5219c3cbb7aacf14c8b.jar 146KB
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
resources.ap_ 256KB
classes
uk
co
senab
photoview
VersionedGestureDetector$EclairDetector.class 2KB
PhotoViewAttacher$1.class 1KB
ScrollerProxy.class 1016B
PhotoViewAttacher$AnimatedZoomRunnable.class 2KB
IPhotoView.class 1KB
VersionedGestureDetector$FroyoDetector.class 2KB
Compat.class 848B
PhotoViewAttacher$OnMatrixChangedListener.class 319B
PhotoViewAttacher$FlingRunnable.class 3KB
VersionedGestureDetector.class 2KB
PhotoView.class 5KB
PhotoViewAttacher.class 18KB
VersionedGestureDetector$OnGestureListener.class 352B
SDK16.class 631B
ScrollerProxy$PreGingerScroller.class 1KB
VersionedGestureDetector$CupcakeDetector.class 3KB
PhotoViewAttacher$OnPhotoTapListener.class 301B
VersionedGestureDetector$FroyoDetector$1.class 2KB
ScrollerProxy$GingerScroller.class 1KB
sample
R$string.class 816B
R$layout.class 433B
ViewPagerActivity$SamplePagerAdapter.class 2KB
SimpleSampleActivity$MatrixChangeListener.class 1KB
R$drawable.class 548B
HackyViewPager.class 774B
R$menu.class 423B
R.class 657B
LauncherActivity.class 2KB
BuildConfig.class 365B
SimpleSampleActivity.class 4KB
R$attr.class 370B
R$id.class 822B
SimpleSampleActivity$PhotoTapListener.class 2KB
ViewPagerActivity.class 994B
PhotoViewAttacher$OnViewTapListener.class 298B
classes.dex 467KB
lint.xml 53B
AndroidManifest.xml 836B
LICENSE 11KB
libs
android-support-v4.jar 377KB
src
uk
co
senab
photoview
VersionedGestureDetector.java 7KB
PhotoViewAttacher.java 25KB
Compat.java 450B
SDK16.java 982B
ScrollerProxy.java 3KB
IPhotoView.java 5KB
PhotoView.java 4KB
sample
HackyViewPager.java 928B
SimpleSampleActivity.java 4KB
LauncherActivity.java 2KB
ViewPagerActivity.java 2KB
project.properties 602B
res
values
strings.xml 677B
layout
activity_main.xml 691B
drawable-ldpi
ic_launcher.png 3KB
drawable-hdpi
ic_launcher.png 7KB
a1.jpg 70KB
a2.jpg 42KB
a3.jpg 20KB
drawable-nodpi
wallpaper.jpg 92KB
drawable-mdpi
ic_launcher.png 4KB
drawable-xhdpi
ic_launcher.png 11KB
menu
main_menu.xml 1KB
.classpath 364B
gen
uk
co
senab
photoview
sample
R.java 2KB
BuildConfig.java 170B
assets
共 78 条
- 1
a393020220
- 粉丝: 5
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
- 5
- 6
前往页