Android多點觸控實現圖片自由縮放_Android

來源:互聯網
上載者:User

Android多點觸控涉及到的知識點

1、ScaleGestureDetector
2、OnScaleGestureListener
3、Matrix
4、OnTouchListener

四個知識點需要瞭解一下,需要注意的是Matrix在記憶體中是一個一維數組,操控圖片的Matrxi是一個3X3的矩陣,在記憶體中也就是一個大小為9的一維數組。

實現多點觸控,自由變化圖片

1、 ImageView的基礎上繼承

2、因為要在圖片載入完成就擷取到相關的屬性,所以實現OnGlobalLayoutListener介面,並實現方法onGlobalLayout

註冊OnGlobalLayoutListener介面:

 @Overrideprotected void onAttachedToWindow() {  super.onAttachedToWindow();  //註冊 OnGlobalLayoutListener  getViewTreeObserver().addOnGlobalLayoutListener(this);}@Overrideprotected void onDetachedFromWindow() {  super.onDetachedFromWindow();  //登出 OnGlobalLayoutListener  getViewTreeObserver().removeOnGlobalLayoutListener(this);}

實現onGlobalLayout方法

@Overridepublic void onGlobalLayout() {//因為要在載入完成的時候就擷取到圖片的寬高 然後讓圖片的寬高去適應控制項的寬高大小 isOnce只在第一次載入到時候處理  if (isOnce) {    //下一步3 擷取相關屬性 並做處理    isOnce = false;  }}

3、

 //擷取控制項的寬高 int width = getWidth();   int height = getHeight();   //擷取圖片   Drawable drawable = getDrawable();   if (null == drawable) {     return;   }   //擷取到圖片的寬高 **根據drawable的這兩個方法擷取   int dw = drawable.getIntrinsicWidth();   int dh = drawable.getIntrinsicHeight();//定義一個圖片縮放值 float scale = 1.0f;接下來就是根據圖片的寬和高 控制項的寬和高 去設定這個scale值 //當圖片的寬大於了控制項的寬 圖片的高小於控制項的高if (dw > width && dh < height) {    scale = width * 1.0f / dw;  }  //當圖片的寬小於了控制項的寬 圖片的高大於控制項的高if (dw < width && dh > height) {   scale = height * 1.0f / dh; }if ((dw > width && dh > height) || (dw < width && dh < height)) {  scale = Math.min((width * 1.0f / dw), (height * 1.0f / dh));}//初始化三個縮放的值    mInitScale = scale;//正常情況下的 縮放值    mMidScale = scale * 2; //    mMaxScale = scale * 4;//最大的縮放值//將圖片初始化載入到控制項的正中心位置    //計算橫縱需要移動的位移值    float dx = getWidth() / 2f - dw / 2f;    float dy = getHeight() / 2f - dh / 2f;    //使用矩陣控製圖片的平移和縮放    mMatrix.postTranslate(dx, dy);    //縮放的時候要指定縮放基準點    mMatrix.postScale(mInitScale, mInitScale, getWidth() / 2f, getHeight() / 2f);    //通過設定Matrix改變ImageView    setImageMatrix(mMatrix);

4、接下來就是ScaleGestureDetector

//初始化 this是OnScaleGestureListener 對象 mScaleGestureDetector = new ScaleGestureDetector(context, this); //要通過ScaleGestureDetector去操控觸摸事件,那還要實現OnTouchListener介面並實現onTouch方法,在該方法中將觸摸事件傳遞給mScaleGestureDetector 對象。@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {  //將觸摸事件傳遞給ScaleGesture  mScaleGestureDetector.onTouchEvent(motionEvent);  return true;}  //設定監聽  setOnTouchListener(this);

5、OnScaleGestureListener 中的重要方法了

 //使用ScaleGestureListener去實現多點觸控@Overridepublic boolean onScale(ScaleGestureDetector scaleGestureDetector) {  if (null == getDrawable()) {    return true;  }//下一步6 處理return true;}

6、

 //縮放中  //擷取當前圖片縮放scale  float scale = getCurrentScale();  //擷取縮放因子  float scaleFactor = scaleGestureDetector.getScaleFactor();  //縮放值達到最大和最小的情況 scaleFactor>1表示正在放大 <1表示正在縮小  if ((scale < mMaxScale && scaleFactor > 1.0f) || scale > mInitScale && scaleFactor < 1.0f) {    if (scale * scaleFactor < mInitScale) {      scaleFactor = mInitScale / scale;    } else if (scale * scaleFactor > mMaxScale) {      scaleFactor = mMaxScale / scale;    }  }  //根據縮放因子去設定圖片的縮放 根據多點的中心去縮放 scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY()縮放中心點一定是手指觸摸的中心點    mMatrix.postScale(scaleFactor, scaleFactor, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY());  //因為縮放的中心點會改變 所以要控製圖片的邊界處理*** 如果不處理,中心點會根據你手指位置的不同發生改變,那麼圖片位置會錯亂  checkoutBounds(); //下一步 7  setImageMatrix(mMatrix);

7、checkoutBounds()

 private void checkoutBounds() {  //通過矩陣要擷取到縮放後圖片的大小和座標  Drawable drawable = getDrawable();  if (null != drawable) {    RectF rectF = getScaleMatrix(drawable); //下一步 8    //擷取控制項的寬高    int width = getWidth();    int height = getHeight();    //聲明 x y位移值 如果偏離了控制項需要移動回去    float detalX = 0;    float detalY = 0;    if (rectF.width() >= width) {      //圖片的寬大於等於了控制項的寬,為了讓寬留白邊,計算出應該左右移動的位移值      if (0 < rectF.left) {        //左邊留空白了 那就應該像左移動        detalX = -rectF.left;      } else if (rectF.right < width) {        detalX = width - rectF.right;      }    }    //高度控制    if (rectF.height() >= height) {      if (0 < rectF.top) {        detalY = -rectF.top;      } else if (rectF.bottom < height) {        detalY = height - rectF.bottom;      }    }    //圖片寬和高小於控制項寬高的情況,讓圖片置中顯示    if (rectF.width() < width) {      //計算位移值      detalX = width / 2f - rectF.right + rectF.width() / 2f;    }    if (rectF.height() < height) {      detalY = height / 2f - rectF.bottom + rectF.height() / 2f;    }    mMatrix.postTranslate(detalX, detalY);}

8、getScaleMatrix(drawable) 該方法其他地方也可以效仿**

//通過矩陣 去擷取到縮放後的圖片的四個頂點座標public RectF getScaleMatrix(Drawable drawable) {  Matrix matrix = mMatrix;  //圖片的四個點座標  RectF rectF = new RectF(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  matrix.mapRect(rectF);  return rectF;}

通過該控制項可以熟悉一下多點觸控的實現 和圖形矩陣的知識

Demo地址ZoomImageView

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.