Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android實現ImageView圖片雙擊放大及縮小

Android實現ImageView圖片雙擊放大及縮小

編輯:關於Android編程

本文實例介紹了Android實現ImageView圖片雙擊放大及縮小的相關技巧,分享給大家供大家參考,具體內容如下

public class DoubleScaleImageView extends ImageView implements OnTouchListener, OnGlobalLayoutListener {
  private boolean isFirst = false;
  private float doubleScale;// 雙擊放大的值
  private Matrix mScaleMatrix;
  private float defaultScale;// 默認的縮放值
  private int mLastPinterCount;// 記錄上一次多點觸控的數量
  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是一個距離,表示滑動的時候,手的移動要大於這個距離才開始移動控件。如果小於這個距離就不觸發移動控件
    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附加到窗體上時調用該方法
    super.onAttachedToWindow();
    getViewTreeObserver().addOnGlobalLayoutListener(this);
  }
  @SuppressWarnings("deprecation")
  @Override
  protected void onDetachedFromWindow() {// 將視圖從窗體上分離的時候調用該方法。
    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;
      }
      // 如果圖片的寬度都 大於或小於控件寬度,我們則要對圖片進行對應縮放,保證圖片占滿控件
      if ((imageWidth > width && imageHeight > height) || (imageWidth < width && imageHeight < height)) {
        scale = Math.min(width * 1.0f / imageWidth, height * 1.0f / imageHeight);
      }
      // 初始化對應的縮放值
      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();// 獲取放在屏幕上的手指數量
    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];
  }
}

以上就是安卓實現ImageView圖片雙擊放大及縮小的全部代碼,希望對大家的學習有所幫助。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved