国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

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

2019-12-12 04:22:16
字體:
來源:轉載
供稿:網友

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 荔波县| 琼海市| 简阳市| 巍山| 贵定县| 嘉义县| 呼和浩特市| 乌拉特后旗| 观塘区| 陆川县| 绵竹市| 博爱县| 滦南县| 乌什县| 北海市| 磐石市| 天气| 肥西县| 屏边| 建始县| 临西县| 成安县| 儋州市| 贵港市| 珲春市| 八宿县| 双流县| 义马市| 攀枝花市| 麦盖提县| 通道| 南郑县| 桐柏县| 朝阳区| 商水县| 五华县| 宽城| 乌兰察布市| 麻江县| 搜索| 伊宁市|