实习第八天:surfaceView实现图片缩放拖动功能

原文地址:http://blog.csdn.net/sunnyfans/article/details/17969531

问题:采用surface来实现多点触摸缩放,拖动显示功能。

[java]  view plain  copy
 
  1. public class MySurfaceView3 extends SurfaceView implements  
  2.         SurfaceHolder.Callback, OnTouchListener {  
  3.   
  4.     private static final int NONE = 0;// 原始  
  5.     private static final int DRAG = 1;// 拖动  
  6.     private static final int ZOOM = 2;// 放大  
  7.     private int mStatus = NONE;  
  8.   
  9.     private static final float MAX_ZOOM_SCALE = 4.0f;  
  10.     private static final float MIN_ZOOM_SCALE = 1.0f;  
  11.     private static final float FLOAT_TYPE = 1.0f;  
  12.     private float mCurrentMaxScale = MAX_ZOOM_SCALE;  
  13.     private float mCurrentScale = 1.0f;  
  14.   
  15.     private Rect mRectSrc = new Rect(); // used for render image.  
  16.     private Rect mRectDes = new Rect(); // used for store size of monitor.  
  17.   
  18.     private int mCenterX, mCenterY;  
  19.     int mSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth;  
  20.   
  21.     private PointF mStartPoint = new PointF();  
  22.     private float mStartDistance = 0f;  
  23.   
  24.     private SurfaceHolder mSurHolder = null;  
  25.     private Bitmap mBitmap;  
  26.   
  27.     public MySurfaceView3(Context context, AttributeSet attrs) {  
  28.         super(context, attrs);  
  29.         mSurHolder = getHolder();  
  30.         mSurHolder.addCallback(this);  
  31.         this.setOnTouchListener(this);  
  32.   
  33.     }  
  34.   
  35.     private void init() {  
  36.         mCurrentMaxScale = Math.max(  
  37.                 MIN_ZOOM_SCALE,  
  38.                 4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f  
  39.                         * mImageWidth / mSurfaceWidth));  
  40.         mCurrentScale = MIN_ZOOM_SCALE;  
  41.         mCenterX = mImageWidth / 2;  
  42.         mCenterY = mImageHeight / 2;  
  43.         calcRect();  
  44.   
  45.     }  
  46.   
  47.     private void adjustCenter() {  
  48.         int w = mRectSrc.right - mRectSrc.left;  
  49.         int h = mRectSrc.bottom - mRectSrc.top;  
  50.   
  51.         if (mCenterX - w / 2 < 0) {  
  52.             mCenterX = w / 2;  
  53.             mRectSrc.left = 0;  
  54.             mRectSrc.right = w;  
  55.         } else if (mCenterX + w / 2 >= mImageWidth) {  
  56.             mCenterX = mImageWidth - w / 2;  
  57.             mRectSrc.right = mImageWidth;  
  58.             mRectSrc.left = mRectSrc.right - w;  
  59.   
  60.         } else {  
  61.             mRectSrc.left = mCenterX - w / 2;  
  62.             mRectSrc.right = mRectSrc.left + w;  
  63.         }  
  64.   
  65.         if (mCenterY - h / 2 < 0) {  
  66.             mCenterY = h / 2;  
  67.             mRectSrc.top = 0;  
  68.             mRectSrc.bottom = h;  
  69.         } else if (mCenterY + h / 2 >= mImageHeight) {  
  70.             mCenterY = mImageHeight - h / 2;  
  71.             mRectSrc.bottom = mImageHeight;  
  72.             mRectSrc.top = mRectSrc.bottom - h;  
  73.         } else {  
  74.             mRectSrc.top = mCenterY - h / 2;  
  75.             mRectSrc.bottom = mRectSrc.top + h;  
  76.         }  
  77.   
  78.     }  
  79.   
  80.     private void calcRect() {  
  81.         int w, h;  
  82.         float imageRatio, surfaceRatio;  
  83.         imageRatio = FLOAT_TYPE * mImageWidth / mImageHeight;  
  84.         surfaceRatio = FLOAT_TYPE * mSurfaceWidth / mSurfaceHeight;  
  85.   
  86.         if (imageRatio < surfaceRatio) {  
  87.             h = mSurfaceHeight;  
  88.             w = (int) (h * imageRatio);  
  89.         } else {  
  90.             w = mSurfaceWidth;  
  91.             h = (int) (w / imageRatio);  
  92.         }  
  93.   
  94.         if (mCurrentScale > MIN_ZOOM_SCALE) {  
  95.             w = Math.min(mSurfaceWidth, (int) (w * mCurrentScale));  
  96.             h = Math.min(mSurfaceHeight, (int) (h * mCurrentScale));  
  97.         } else {  
  98.             mCurrentScale = MIN_ZOOM_SCALE;  
  99.         }  
  100.   
  101.         mRectDes.left = (mSurfaceWidth - w) / 2;  
  102.         mRectDes.top = (mSurfaceHeight - h) / 2;  
  103.         mRectDes.right = mRectDes.left + w;  
  104.         mRectDes.bottom = mRectDes.top + h;  
  105.   
  106.         float curImageRatio = FLOAT_TYPE * w / h;  
  107.         int h2, w2;  
  108.         if (curImageRatio > imageRatio) {  
  109.             h2 = (int) (mImageHeight / mCurrentScale);  
  110.             w2 = (int) (h2 * curImageRatio);  
  111.         } else {  
  112.   
  113.             w2 = (int) (mImageWidth / mCurrentScale);  
  114.             h2 = (int) (w2 / curImageRatio);  
  115.         }  
  116.         mRectSrc.left = mCenterX - w2 / 2;  
  117.         mRectSrc.top = mCenterY - h2 / 2;  
  118.         mRectSrc.right = mRectSrc.left + w2;  
  119.         mRectSrc.bottom = mRectSrc.top + h2;  
  120.     }  
  121.   
  122.     public void setMaxZoom(float value) {  
  123.         mCurrentMaxScale = value;  
  124.     }  
  125.   
  126.     public void setBitmap(Bitmap b) {  
  127.   
  128.         if (b == null) {  
  129.             return;  
  130.         }  
  131.         synchronized (MySurfaceView3.class) {  
  132.             mBitmap = b;  
  133.             if (mImageHeight != mBitmap.getHeight()  
  134.                     || mImageWidth != mBitmap.getWidth()) {  
  135.                 mImageHeight = mBitmap.getHeight();  
  136.                 mImageWidth = mBitmap.getWidth();  
  137.                 init();  
  138.             }  
  139.             showBitmap();  
  140.         }  
  141.   
  142.     }  
  143.   
  144.     private void showBitmap() {  
  145.         synchronized (MySurfaceView3.class) {  
  146.             Canvas c = getHolder().lockCanvas();  
  147.             if (c != null && mBitmap != null) {  
  148.                 c.drawColor(Color.GRAY);  
  149.                 c.drawBitmap(mBitmap, mRectSrc, mRectDes, null);  
  150.                 getHolder().unlockCanvasAndPost(c);  
  151.             }  
  152.         }  
  153.     }  
  154.   
  155.     private void dragAction(MotionEvent event) {  
  156.   
  157.         synchronized (MySurfaceView3.class) {  
  158.             PointF currentPoint = new PointF();  
  159.             currentPoint.set(event.getX(), event.getY());  
  160.             int offsetX = (int) currentPoint.x - (int) mStartPoint.x;  
  161.             int offsetY = (int) currentPoint.y - (int) mStartPoint.y;  
  162.             mStartPoint = currentPoint;  
  163.   
  164.             mCenterX -= offsetX;  
  165.             mCenterY -= offsetY;  
  166.   
  167.             adjustCenter();  
  168.             showBitmap();  
  169.         }  
  170.     }  
  171.   
  172.     private void zoomAcition(MotionEvent event) {  
  173.   
  174.         synchronized (MySurfaceView3.class) {  
  175.   
  176.             float newDist = spacing(event);  
  177.             float scale = newDist / mStartDistance;  
  178.             mStartDistance = newDist;  
  179.   
  180.             mCurrentScale *= scale;  
  181.             mCurrentScale = Math.max(FLOAT_TYPE,  
  182.                     Math.min(mCurrentScale, mCurrentMaxScale));  
  183.   
  184.             calcRect();  
  185.             adjustCenter();  
  186.             showBitmap();  
  187.         }  
  188.     }  
  189.   
  190.     @Override  
  191.     public boolean onTouch(View v, MotionEvent event) {  
  192.   
  193.         switch (event.getAction() & MotionEvent.ACTION_MASK) {  
  194.         case MotionEvent.ACTION_DOWN:  
  195.             mStartPoint.set(event.getX(), event.getY());  
  196.             mStatus = DRAG;  
  197.             break;  
  198.   
  199.         case MotionEvent.ACTION_POINTER_DOWN:  
  200.             float distance = spacing(event);  
  201.             if (distance > 10f) {  
  202.   
  203.                 mStatus = ZOOM;  
  204.                 mStartDistance = distance;  
  205.             }  
  206.   
  207.             break;  
  208.   
  209.         case MotionEvent.ACTION_MOVE:  
  210.             if (mStatus == DRAG) {  
  211.                 dragAction(event);  
  212.             } else {  
  213.   
  214.                 if (event.getPointerCount() == 1)  
  215.                     return true;  
  216.                 zoomAcition(event);  
  217.             }  
  218.             break;  
  219.         case MotionEvent.ACTION_UP:  
  220.         case MotionEvent.ACTION_POINTER_UP:  
  221.             mStatus = NONE;  
  222.             break;  
  223.         default:  
  224.             break;  
  225.         }  
  226.   
  227.         return true;  
  228.     }  
  229.   
  230.     private float spacing(MotionEvent event) {  
  231.         float x = event.getX(0) - event.getX(1);  
  232.         float y = event.getY(0) - event.getY(1);  
  233.         return (float) Math.sqrt(x * x + y * y);  
  234.     }  
  235.   
  236.     @Override  
  237.     public void surfaceCreated(SurfaceHolder holder) {  
  238.         // TODO Auto-generated method stub  
  239.     }  
  240.   
  241.     // 初始化  
  242.     @Override  
  243.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  244.             int height) {  
  245.   
  246.         synchronized (MySurfaceView3.class) {  
  247.             mRectDes.set(00, width, height);  
  248.             mSurfaceHeight = height;  
  249.             mSurfaceWidth = width;  
  250.             init();  
  251.             if (mBitmap != null) {  
  252.                 showBitmap();  
  253.             }  
  254.         }  
  255.     }  
  256.   
  257.     @Override  
  258.     public void surfaceDestroyed(SurfaceHolder holder) {  
  259.   
  260.     }  
  261.   
  262. }  

你可能感兴趣的:(实习)