Android實現(xiàn)ImageView圖片雙擊放大及縮小
本文實例介紹了Android實現(xiàn)ImageView圖片雙擊放大及縮小的相關(guān)技巧,分享給大家供大家參考,具體內(nèi)容如下
public class DoubleScaleImageView extends ImageView implements OnTouchListener, OnGlobalLayoutListener {
private boolean isFirst = false;
private float doubleScale;// 雙擊放大的值
private Matrix mScaleMatrix;
private float defaultScale;// 默認的縮放值
private int mLastPinterCount;// 記錄上一次多點觸控的數(shù)量
private float mLastX;
private float mLastY;
private int mTouchSlop;
private boolean isCanDrag;
private boolean isCheckLeft;
private boolean isCheckTop;
private GestureDetector mGestureDetector;
public DoubleScaleImageView(Context context) {
this(context, null);
}
public DoubleScaleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@SuppressLint("ClickableViewAccessibility")
public DoubleScaleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScaleMatrix = new Matrix();
setScaleType(ScaleType.MATRIX);
setOnTouchListener(this);
// getScaledTouchSlop是一個距離,表示滑動的時候,手的移動要大于這個距離才開始移動控件。如果小于這個距離就不觸發(fā)移動控件
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
if (getScale() < doubleScale) {
mScaleMatrix.postScale(doubleScale / getScale(), doubleScale / getScale(), x, y);// 放大
}
else {
mScaleMatrix.postScale(defaultScale / getScale(), defaultScale / getScale(), x, y);// 縮小
}
setImageMatrix(mScaleMatrix);
return super.onDoubleTap(e);
}
});
}
@Override
protected void onAttachedToWindow() {// view附加到窗體上時調(diào)用該方法
super.onAttachedToWindow();
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@SuppressWarnings("deprecation")
@Override
protected void onDetachedFromWindow() {// 將視圖從窗體上分離的時候調(diào)用該方法。
super.onDetachedFromWindow();
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
@Override
public void onGlobalLayout() {// 在這個方法中獲取ImageView加載完成后的圖片
if (!isFirst) {
// 獲取控件的寬度和高度
int width = getWidth();
int height = getHeight();
// 得到我們的圖片以及圖片的寬度及高度
Drawable drawable = getDrawable();
if (drawable == null) { return; }
int imageWidth = drawable.getIntrinsicWidth();// 圖片的寬度
int imageHeight = drawable.getIntrinsicHeight();// 圖片的高度
float scale = 1.0f;
// 如果圖片寬度大于控件寬度,但是圖片高度小于控件 高度,我們要縮小圖片
if (imageWidth > width && imageHeight < height) {
scale = width * 1.0f / imageWidth;
}
// 如果圖片寬度小于控件寬度,但是圖片高度大于控件 高度,我們要縮小圖片
if (imageWidth < width && imageHeight > height) {
scale = height * 1.0f / imageHeight;
}
// 如果圖片的寬度都 大于或小于控件寬度,我們則要對圖片進行對應(yīng)縮放,保證圖片占滿控件
if ((imageWidth > width && imageHeight > height) || (imageWidth < width && imageHeight < height)) {
scale = Math.min(width * 1.0f / imageWidth, height * 1.0f / imageHeight);
}
// 初始化對應(yīng)的縮放值
defaultScale = scale;
doubleScale = defaultScale * 2;
// 圖片縮放后,將圖片要移動到控件中心
int dx = width / 2 - imageWidth / 2;
int dy = height / 2 - imageHeight / 2;
mScaleMatrix.postTranslate(dx, dy);
mScaleMatrix.postScale(defaultScale, defaultScale, width / 2, height / 2);
setImageMatrix(mScaleMatrix);
isFirst = true;
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mGestureDetector.onTouchEvent(event)) { return true; }
float x = 0;
float y = 0;
int pointerCount = event.getPointerCount();// 獲取放在屏幕上的手指數(shù)量
for (int i = 0; i < pointerCount; i++) {
x += event.getX(i);
y += event.getY(i);
}
x /= pointerCount;
y /= pointerCount;
if (mLastPinterCount != pointerCount) {
isCanDrag = false;
mLastX = x;
mLastY = y;
}
mLastPinterCount = pointerCount;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mLastX;
float dy = y - mLastY;
isCanDrag = isMove(dx, dy);
if (isCanDrag) {
RectF rectf = getMatrixRectf();
if (null != getDrawable()) {
isCheckLeft = isCheckTop = true;
if (rectf.width() < getWidth()) {// 如果圖片寬度小于控件寬度(屏幕寬度)不允許橫向移動
dx = 0;
isCheckLeft = false;
}
if (rectf.height() < getHeight()) {// 如果圖片高度小于控件高度(屏幕高度)不允許縱向移動
dy = 0;
isCheckTop = false;
}
mScaleMatrix.postTranslate(dx, dy);
checkTranslateWithBorder();
setImageMatrix(mScaleMatrix);
}
}
mLastX = x;
mLastY = y;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mLastPinterCount = 0;
break;
}
return true;
}
/**
* 移動圖片時進行邊界檢查
* @description:
* @date 2016-1-8 下午4:02:24
*/
private void checkTranslateWithBorder() {
RectF rectf = getMatrixRectf();
float delX = 0;
float delY = 0;
int width = getWidth();
int height = getHeight();
if (rectf.top > 0 && isCheckTop) {
delY = -rectf.top;
}
if (rectf.bottom < height && isCheckTop) {
delY = height - rectf.bottom;
}
if (rectf.left > 0 && isCheckLeft) {
delX = -rectf.left;
}
if (rectf.right < width && isCheckLeft) {
delX = width - rectf.right;
}
mScaleMatrix.postTranslate(delX, delY);
}
// 判斷是否有移動
private boolean isMove(float x, float y) {
return Math.sqrt(x * x + y * y) > mTouchSlop;
}
/**
* 獲取圖片的位置
* @description:
* @date 2016-1-8 上午9:02:10
*/
private RectF getMatrixRectf() {
Matrix matrix = mScaleMatrix;
RectF recft = new RectF();
if (getDrawable() != null) {
recft.set(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
matrix.mapRect(recft);
}
return recft;
}
// 獲取當前圖片的縮放值
private float getScale() {
float values[] = new float[9];
mScaleMatrix.getValues(values);
return values[Matrix.MSCALE_X];
}
}
以上就是安卓實現(xiàn)ImageView圖片雙擊放大及縮小的全部代碼,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
Android UI系列-----ScrollView和HorizontalScrollView的詳解
本篇文章主要是介紹的Android UI系列-----ScrollView和HorizontalScrollView,ScrollView和HorizontalScrollView都是布局容器,有需要的可以了解一下。2016-11-11
Android TextView設(shè)置不同的顏色字體
這篇文章主要為大家詳細介紹了Android TextView設(shè)置不同的顏色字體,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12
Android布局自定義Shap圓形ImageView可以單獨設(shè)置背景與圖片
這篇文章主要介紹了Android布局自定義Shap圓形ImageView可以單獨設(shè)置背景與圖片 的相關(guān)資料,需要的朋友可以參考下2016-01-01
Android性能優(yōu)化之利用Rxlifecycle解決RxJava內(nèi)存泄漏詳解
RxJava作為一種響應(yīng)式編程框架,是目前編程界網(wǎng)紅,可謂是家喻戶曉,其簡潔的編碼風(fēng)格、易用易讀的鏈式方法調(diào)用、強大的異步支持等使得RxJava被廣泛使用。2017-01-01
Android中使用AndroidTestCase的方法實例
這篇文章主要介紹了Android中使用AndroidTestCase的方法實例,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下2015-04-04
Android開發(fā)之5.0activity跳轉(zhuǎn)時共享元素的使用方法
下面小編就為大家分享一篇Android開發(fā)之5.0activity跳轉(zhuǎn)時共享元素的使用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
Android嵌套滾動與協(xié)調(diào)滾動的實現(xiàn)方式匯總
如何實現(xiàn)這種協(xié)調(diào)滾動的布局呢,我們使用CoordinatorLayout+AppBarLayout或者CoordinatorLayout+Behavior實現(xiàn),另一種方案是MotionLayout,我們看看都是怎么實現(xiàn)的吧2022-06-06

