Android手势滑动实现两点触摸缩放图片

Android手势滑动实现两点触摸缩放图片,第1张

概述学习安卓手势滑动,多点触摸放大缩小图片,分享给大家供大家参考,具体代码如下

学习安卓手势滑动,多点触摸放大缩小图片,分享给大家供大家参考,具体代码如下
1.布局文件如下main.xml

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:orIEntation="vertical" > <!-- 引用自定义控件 --> <com.ymw.zoomimage.ZoomImageVIEw  androID:ID="@+ID/image"  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content" > </com.ymw.zoomimage.ZoomImageVIEw></linearLayout>

2.自定义缩放图片控件ZoomImageVIEw.java代码:

package com.ymw.zoomimage;import java.util.Observable;import java.util.Observer;import androID.content.Context;import androID.graphics.Bitmap;import androID.graphics.Canvas;import androID.graphics.Paint;import androID.graphics.Rect;import androID.util.AttributeSet;import androID.util.Log;import androID.vIEw.MotionEvent;import androID.vIEw.VIEw;public class ZoomImageVIEw extends VIEw implements Observer { /** Paint object used when drawing bitmap. */ private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); /** Rectangle used (and re-used) for cropPing source image. */ private final Rect mRectSrc = new Rect(); /** Rectangle used (and re-used) for specifying drawing area on canvas. */ private final Rect mRectDst = new Rect(); /** Object holding aspect quotIEnt */ private final AspectQuotIEnt mAspectQuotIEnt = new AspectQuotIEnt(); /** The bitmap that we're zooming in,and drawing on the screen. */ private Bitmap mBitmap; /** State of the zoom. */ private ZoomState mState; private BasicZoomControl mZoomControl; private BasicZoomListener mZoomListener; public ZoomImageVIEw(Context context,AttributeSet attrs) {  super(context,attrs);  mZoomControl = new BasicZoomControl();  mZoomListener = new BasicZoomListener();  mZoomListener.setZoomControl(mZoomControl);  setZoomState(mZoomControl.getZoomState());  setontouchListener(mZoomListener);  mZoomControl.setAspectQuotIEnt(getAspectQuotIEnt()); } public voID zoomImage(float f,float x,float y) {  mZoomControl.zoom(f,x,y); } public voID setimage(Bitmap bitmap) {  mBitmap = bitmap;  mAspectQuotIEnt.updateAspectQuotIEnt(getWIDth(),getHeight(),mBitmap.getWIDth(),mBitmap.getHeight());  mAspectQuotIEnt.notifyObservers();  invalIDate(); } private voID setZoomState(ZoomState state) {  if (mState != null) {   mState.deleteObserver(this);  }  mState = state;  mState.addobserver(this);  invalIDate(); } private AspectQuotIEnt getAspectQuotIEnt() {  return mAspectQuotIEnt; } @OverrIDe protected voID onDraw(Canvas canvas) {  if (mBitmap != null && mState != null) {   Log.d("ZoomImageVIEw","OnDraw");   final float aspectQuotIEnt = mAspectQuotIEnt.get();   final int vIEwWIDth = getWIDth();   final int vIEwHeight = getHeight();   final int bitmapWIDth = mBitmap.getWIDth();   final int bitmapHeight = mBitmap.getHeight();   Log.d("ZoomImageVIEw","vIEwWIDth = " + vIEwWIDth);   Log.d("ZoomImageVIEw","vIEwHeight = " + vIEwHeight);   Log.d("ZoomImageVIEw","bitmapWIDth = " + bitmapWIDth);   Log.d("ZoomImageVIEw","bitmapHeight = " + bitmapHeight);   final float panX = mState.getPanX();   final float panY = mState.getPanY();   final float zoomX = mState.getZoomX(aspectQuotIEnt) * vIEwWIDth     / bitmapWIDth;   final float zoomY = mState.getZoomY(aspectQuotIEnt) * vIEwHeight     / bitmapHeight;   // Setup source and destination rectangles   mRectSrc.left = (int) (panX * bitmapWIDth - vIEwWIDth / (zoomX * 2));   mRectSrc.top = (int) (panY * bitmapHeight - vIEwHeight     / (zoomY * 2));   mRectSrc.right = (int) (mRectSrc.left + vIEwWIDth / zoomX);   mRectSrc.bottom = (int) (mRectSrc.top + vIEwHeight / zoomY);   // mRectDst.left = getleft();   mRectDst.left = 0;   mRectDst.top = 0;   // mRectDst.right = getRight();   mRectDst.right = getWIDth();   mRectDst.bottom = getHeight();   // Adjust source rectangle so that it fits within the source image.   if (mRectSrc.left < 0) {    mRectDst.left += -mRectSrc.left * zoomX;    mRectSrc.left = 0;   }   if (mRectSrc.right > bitmapWIDth) {    mRectDst.right -= (mRectSrc.right - bitmapWIDth) * zoomX;    mRectSrc.right = bitmapWIDth;   }   if (mRectSrc.top < 0) {    mRectDst.top += -mRectSrc.top * zoomY;    mRectSrc.top = 0;   }   if (mRectSrc.bottom > bitmapHeight) {    mRectDst.bottom -= (mRectSrc.bottom - bitmapHeight) * zoomY;    mRectSrc.bottom = bitmapHeight;   }   mRectDst.left = 0;   mRectDst.top = 0;   mRectDst.right = vIEwWIDth;   mRectDst.bottom = vIEwHeight;   Log.d("ZoomImageVIEw","mRectSrc.top" + mRectSrc.top);   Log.d("ZoomImageVIEw","mRectSrc.bottom" + mRectSrc.bottom);   Log.d("ZoomImageVIEw","mRectSrc.left" + mRectSrc.left);   Log.d("ZoomImageVIEw","mRectSrc.right" + mRectSrc.right);   Log.d("ZoomImageVIEw","mRectDst.top" + mRectDst.top);   Log.d("ZoomImageVIEw","mRectDst.bottom" + mRectDst.bottom);   Log.d("ZoomImageVIEw","mRectDst.left" + mRectDst.left);   Log.d("ZoomImageVIEw","mRectDst.right" + mRectDst.right);   canvas.drawBitmap(mBitmap,mRectSrc,mRectDst,mPaint);  } } @OverrIDe protected voID onLayout(boolean changed,int left,int top,int right,int bottom) {  super.onLayout(changed,left,top,right,bottom);  mAspectQuotIEnt.updateAspectQuotIEnt(right - left,bottom - top,mBitmap.getHeight());  mAspectQuotIEnt.notifyObservers(); } @OverrIDe public voID update(Observable observable,Object data) {  invalIDate(); } private class BasicZoomListener implements VIEw.OntouchListener {  /** Zoom control to manipulate */  private BasicZoomControl mZoomControl;  private float mFirstX = -1;  private float mFirstY = -1;  private float mSecondX = -1;  private float mSecondY = -1;  private int moldCounts = 0;  /**   * Sets the zoom control to manipulate   *    * @param control   *   Zoom control   */  public voID setZoomControl(BasicZoomControl control) {   mZoomControl = control;  }  public boolean ontouch(VIEw v,MotionEvent event) {   switch (event.getAction()) {   case MotionEvent.ACTION_DOWN:    moldCounts = 1;    mFirstX = event.getX();    mFirstY = event.getY();    break;   case MotionEvent.ACTION_MOVE: {    float fFirstX = event.getX();    float fFirstY = event.getY();    int nCounts = event.getPointerCount();    if (1 == nCounts) {     moldCounts = 1;     float dx = (fFirstX - mFirstX) / v.getWIDth();     float dy = (fFirstY - mFirstY) / v.getHeight();     mZoomControl.pan(-dx,-dy);    } else if (1 == moldCounts) {     mSecondX = event.getX(event.getPointerID(nCounts - 1));     mSecondY = event.getY(event.getPointerID(nCounts - 1));     moldCounts = nCounts;    } else {     float fSecondX = event       .getX(event.getPointerID(nCounts - 1));     float fSecondY = event       .getY(event.getPointerID(nCounts - 1));     double nLengthold = getLength(mFirstX,mFirstY,mSecondX,mSecondY);     double nLengthNow = getLength(fFirstX,fFirstY,fSecondX,fSecondY);     float d = (float) ((nLengthNow - nLengthold) / v.getWIDth());     mZoomControl.zoom((float) Math.pow(20,d),((fFirstX + fSecondX) / 2 / v.getWIDth()),((fFirstY + fSecondY) / 2 / v.getHeight()));     mSecondX = fSecondX;     mSecondY = fSecondY;    }    mFirstX = fFirstX;    mFirstY = fFirstY;    break;   }   }   return true;  }  private double getLength(float x1,float y1,float x2,float y2) {   return Math.sqrt(Math.pow(x1 - x2,2) + Math.pow(y1 - y2,2));  } } private class BasicZoomControl implements Observer {  /** Minimum zoom level limit */  private static final float MIN_ZOOM = 1;  /** Maximum zoom level limit */  private static final float MAX_ZOOM = 16;  /** Zoom state under control */  private final ZoomState mState = new ZoomState();  /** Object holding aspect quotIEnt of vIEw and content */  private AspectQuotIEnt mAspectQuotIEnt;  /**   * Set reference object holding aspect quotIEnt   *    * @param aspectQuotIEnt   *   Object holding aspect quotIEnt   */  public voID setAspectQuotIEnt(AspectQuotIEnt aspectQuotIEnt) {   if (mAspectQuotIEnt != null) {    mAspectQuotIEnt.deleteObserver(this);   }   mAspectQuotIEnt = aspectQuotIEnt;   mAspectQuotIEnt.addobserver(this);  }  /**   * Get zoom state being controlled   *    * @return The zoom state   */  public ZoomState getZoomState() {   return mState;  }  /**   * Zoom   *    * @param f   *   Factor of zoom to apply   * @param x   *   X-coordinate of invariant position   * @param y   *   Y-coordinate of invariant position   */  public voID zoom(float f,float y) {   // Log.d("Zoom","zoom f = " + f);   final float aspectQuotIEnt = mAspectQuotIEnt.get();   final float prevZoomX = mState.getZoomX(aspectQuotIEnt);   final float prevZoomY = mState.getZoomY(aspectQuotIEnt);   mState.setZoom(mState.getZoom() * f);   limitZoom();   final float newZoomX = mState.getZoomX(aspectQuotIEnt);   final float newZoomY = mState.getZoomY(aspectQuotIEnt);   // Pan to keep x and y coordinate invariant   mState.setPanX(mState.getPanX() + (x - .5f)     * (1f / prevZoomX - 1f / newZoomX));   mState.setPanY(mState.getPanY() + (y - .5f)     * (1f / prevZoomY - 1f / newZoomY));   limitPan();   mState.notifyObservers();  }  /**   * Pan   *    * @param dx   *   Amount to pan in x-dimension   * @param dy   *   Amount to pan in y-dimension   */  public voID pan(float dx,float dy) {   final float aspectQuotIEnt = mAspectQuotIEnt.get();   mState.setPanX(mState.getPanX() + dx     / mState.getZoomX(aspectQuotIEnt));   mState.setPanY(mState.getPanY() + dy     / mState.getZoomY(aspectQuotIEnt));   limitPan();   mState.notifyObservers();  }  /**   * Help function to figure out max delta of pan from center position.   *    * @param zoom   *   Zoom value   * @return Max delta of pan   */  private float getMaxPanDelta(float zoom) {   return Math.max(0f,.5f * ((zoom - 1) / zoom));  }  /**   * Force zoom to stay within limits   */  private voID limitZoom() {   if (mState.getZoom() < MIN_ZOOM) {    mState.setZoom(MIN_ZOOM);   } else if (mState.getZoom() > MAX_ZOOM) {    mState.setZoom(MAX_ZOOM);   }  }  /**   * Force pan to stay within limits   */  private voID limitPan() {   final float aspectQuotIEnt = mAspectQuotIEnt.get();   final float zoomX = mState.getZoomX(aspectQuotIEnt);   final float zoomY = mState.getZoomY(aspectQuotIEnt);   final float panMinX = .5f - getMaxPanDelta(zoomX);   final float panMaxX = .5f + getMaxPanDelta(zoomX);   final float panMinY = .5f - getMaxPanDelta(zoomY);   final float panMaxY = .5f + getMaxPanDelta(zoomY);   if (mState.getPanX() < panMinX) {    mState.setPanX(panMinX);   }   if (mState.getPanX() > panMaxX) {    mState.setPanX(panMaxX);   }   if (mState.getPanY() < panMinY) {    mState.setPanY(panMinY);   }   if (mState.getPanY() > panMaxY) {    mState.setPanY(panMaxY);   }  }  // Observable interface implementation  public voID update(Observable observable,Object data) {   limitZoom();   limitPan();  } } private class AspectQuotIEnt extends Observable {  /**   * Aspect quotIEnt   */  private float mAspectQuotIEnt;  // Public methods  /**   * Gets aspect quotIEnt   *    * @return The aspect quotIEnt   */  public float get() {   return mAspectQuotIEnt;  }  /**   * Updates and recalculates aspect quotIEnt based on supplIEd vIEw and   * content dimensions.   *    * @param vIEwWIDth   *   WIDth of vIEw   * @param vIEwHeight   *   Height of vIEw   * @param contentWIDth   *   WIDth of content   * @param contentHeight   *   Height of content   */  public voID updateAspectQuotIEnt(float vIEwWIDth,float vIEwHeight,float contentWIDth,float contentHeight) {   final float aspectQuotIEnt = (contentWIDth / contentHeight)     / (vIEwWIDth / vIEwHeight);   if (aspectQuotIEnt != mAspectQuotIEnt) {    mAspectQuotIEnt = aspectQuotIEnt;    setChanged();   }  } } private class ZoomState extends Observable {  /**   * Zoom level A value of 1.0 means the content fits the vIEw.   */  private float mZoom;  /**   * Pan position x-coordinate X-coordinate of zoom window center   * position,relative to the wIDth of the content.   */  private float mPanX;  /**   * Pan position y-coordinate Y-coordinate of zoom window center   * position,relative to the height of the content.   */  private float mPanY;  // Public methods  /**   * Get current x-pan   *    * @return current x-pan   */  public float getPanX() {   return mPanX;  }  /**   * Get current y-pan   *    * @return Current y-pan   */  public float getPanY() {   return mPanY;  }  /**   * Get current zoom value   *    * @return Current zoom value   */  public float getZoom() {   return mZoom;  }  /**   * Help function for calculating current zoom value in x-dimension   *    * @param aspectQuotIEnt   *   (Aspect ratio content) / (Aspect ratio vIEw)   * @return Current zoom value in x-dimension   */  public float getZoomX(float aspectQuotIEnt) {   return Math.min(mZoom,mZoom * aspectQuotIEnt);  }  /**   * Help function for calculating current zoom value in y-dimension   *    * @param aspectQuotIEnt   *   (Aspect ratio content) / (Aspect ratio vIEw)   * @return Current zoom value in y-dimension   */  public float getZoomY(float aspectQuotIEnt) {   return Math.min(mZoom,mZoom / aspectQuotIEnt);  }  /**   * Set pan-x   *    * @param panX   *   Pan-x value to set   */  public voID setPanX(float panX) {   if (panX != mPanX) {    mPanX = panX;    setChanged();   }  }  /**   * Set pan-y   *    * @param panY   *   Pan-y value to set   */  public voID setPanY(float panY) {   if (panY != mPanY) {    mPanY = panY;    setChanged();   }  }  /**   * Set zoom   *    * @param zoom   *   Zoom value to set   */  public voID setZoom(float zoom) {   if (zoom != mZoom) {    mZoom = zoom;    setChanged();   }  } }}

3.工程主文件MainActivity.java代码:

package com.ymw.zoomimage;import androID.app.Activity;import androID.graphics.Bitmap;import androID.graphics.BitmapFactory;import androID.os.Bundle;public class MainActivity extends Activity { private ZoomImageVIEw zoomimg; @OverrIDe public voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.main);  zoomimg = (ZoomImageVIEw) findVIEwByID(R.ID.image);  Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.a);  zoomimg.setimage(bitmap); }}

以上就是AndroID多点触摸放大缩小图片的示例代码,希望对大家的学习有所帮助。

总结

以上是内存溢出为你收集整理的Android手势滑动实现两点触摸缩放图片全部内容,希望文章能够帮你解决Android手势滑动实现两点触摸缩放图片所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1141208.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存