方法一:

将以下代码写到MulitPointTouchListener.java中,然后对你相应的图片进行OnTouchListener。
例如:imageView.setOnTouchListener(new MulitPointTouchListener ());

在xml中要将ImageView的缩放格式改成Matrix

例如:android:scaleType="matrix"

这样就可以实现图片的缩放了

下面是MulitPointTouchListener.java代码:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 public class MulitPointTouchListener implements OnTouchListener { private static final String TAG = "Touch" ; // These matrices will be used to move and zoom image Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); // We can be in one of these 3 states static final int NONE = 0 ; static final int DRAG = 1 ; static final int ZOOM = 2 ; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; // Log.e("view_width", // view.getImageMatrix()..toString()+"*"+v.getWidth()); // Dump touch event to log dumpEvent(event); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: matrix.set(view.getImageMatrix()); savedMatrix.set(matrix); start.set(event.getX(), event.getY()); //Log.d(TAG, "mode=DRAG"); mode = DRAG; //Log.d(TAG, "mode=NONE"); break ; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); //Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; //Log.d(TAG, "mode=ZOOM"); } break ; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; //Log.e("view.getWidth", view.getWidth() + ""); //Log.e("view.getHeight", view.getHeight() + ""); break ; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); //Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break ; } view.setImageMatrix(matrix); return true ; // indicate event was handled } private void dumpEvent(MotionEvent event) { String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" , "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" }; StringBuilder sb = new StringBuilder(); int action = event.getAction(); int actionCode = action & MotionEvent.ACTION_MASK; sb.append( "event ACTION_" ).append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append( "(pid " ).append( action >> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append( ")" ); } sb.append( "[" ); for ( int i = 0 ; i < event.getPointerCount(); i++) { sb.append( "#" ).append(i); sb.append( "(pid " ).append(event.getPointerId(i)); sb.append( ")=" ).append(( int ) event.getX(i)); sb.append( "," ).append(( int ) event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append( ";" ); } sb.append( "]" ); //Log.d(TAG, sb.toString()); } private float spacing(MotionEvent event) { float x = event.getX( 0 ) - event.getX( 1 ); float y = event.getY( 0 ) - event.getY( 1 ); return FloatMath.sqrt(x * x + y * y); } private void midPoint(PointF point, MotionEvent event) { float x = event.getX( 0 ) + event.getX( 1 ); float y = event.getY( 0 ) + event.getY( 1 ); point.set(x / 2 , y / 2 ); } }

方法二:自定义一个ImageView,例如TouchImageView:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 import android.content.Context; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; import android.widget.ImageView; public class TouchImageView extends ImageView { Matrix matrix; // We can be in one of these 3 states static final int NONE = 0 ; static final int DRAG = 1 ; static final int ZOOM = 2 ; int mode = NONE; // Remember some things for zooming PointF last = new PointF(); PointF start = new PointF(); float minScale = 1f; float maxScale = 3f; float [] m; int viewWidth, viewHeight; static final int CLICK = 3 ; float saveScale = 1f; protected float origWidth, origHeight; int oldMeasuredWidth, oldMeasuredHeight; ScaleGestureDetector mScaleDetector; Context context; public TouchImageView(Context context) { super (context); sharedConstructing(context); } public TouchImageView(Context context, AttributeSet attrs) { super (context, attrs); sharedConstructing(context); } private void sharedConstructing(Context context) { super .setClickable( true ); this .context = context; mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); matrix = new Matrix(); m = new float [ 9 ]; setImageMatrix(matrix); setScaleType(ScaleType.MATRIX); setOnTouchListener( new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mScaleDetector.onTouchEvent(event); PointF curr = new PointF(event.getX(), event.getY()); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: last.set(curr); start.set(last); mode = DRAG; break ; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { float deltaX = curr.x - last.x; float deltaY = curr.y - last.y; float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale); float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale); matrix.postTranslate(fixTransX, fixTransY); fixTrans(); last.set(curr.x, curr.y); } break ; case MotionEvent.ACTION_UP: mode = NONE; int xDiff = ( int ) Math.abs(curr.x - start.x); int yDiff = ( int ) Math.abs(curr.y - start.y); if (xDiff < CLICK && yDiff < CLICK) performClick(); break ; case MotionEvent.ACTION_POINTER_UP: mode = NONE; break ; } setImageMatrix(matrix); invalidate(); return true ; // indicate event was handled } }); } public void setMaxZoom( float x) { maxScale = x; } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScaleBegin(ScaleGestureDetector detector) { mode = ZOOM; return true ; } @Override public boolean onScale(ScaleGestureDetector detector) { float mScaleFactor = detector.getScaleFactor(); float origScale = saveScale; saveScale *= mScaleFactor; if (saveScale > maxScale) { saveScale = maxScale; mScaleFactor = maxScale / origScale; } else if (saveScale < minScale) { saveScale = minScale; mScaleFactor = minScale / origScale; } if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight) matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2 , viewHeight / 2 ); else matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); fixTrans(); return true ; } } void fixTrans() { matrix.getValues(m); float transX = m[Matrix.MTRANS_X]; float transY = m[Matrix.MTRANS_Y]; float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale); float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale); if (fixTransX != 0 || fixTransY != 0 ) matrix.postTranslate(fixTransX, fixTransY); } float getFixTrans( float trans, float viewSize, float contentSize) { float minTrans, maxTrans; if (contentSize <= viewSize) { minTrans = 0 ; maxTrans = viewSize - contentSize; } else { minTrans = viewSize - contentSize; maxTrans = 0 ; } if (trans < minTrans) return -trans + minTrans; if (trans > maxTrans) return -trans + maxTrans; return 0 ; } float getFixDragTrans( float delta, float viewSize, float contentSize) { if (contentSize <= viewSize) { return 0 ; } return delta; } @Override protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) { super .onMeasure(widthMeasureSpec, heightMeasureSpec); viewWidth = MeasureSpec.getSize(widthMeasureSpec); viewHeight = MeasureSpec.getSize(heightMeasureSpec); // // Rescales image on rotation // if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight || viewWidth == 0 || viewHeight == 0 ) return ; oldMeasuredHeight = viewHeight; oldMeasuredWidth = viewWidth; if (saveScale == 1 ) { //Fit to screen. float scale; Drawable drawable = getDrawable(); if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0 ) return ; int bmWidth = drawable.getIntrinsicWidth(); int bmHeight = drawable.getIntrinsicHeight(); Log.d( "bmSize" , "bmWidth: " + bmWidth + " bmHeight : " + bmHeight); float scaleX = ( float ) viewWidth / (

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. AndroidContentProvider ContentResolver和ContentObserver的使
  3. android studio 打包jar 及混淆
  4. Android中在代码中设置控件的宽和高
  5. service 的调用【转】
  6. Dialog使用findViewById 报空指针异常
  7. Android中常见面试题
  8. GPS在Android的使用
  9. 【Android(安卓)开发教程】使用Intent传递数据

随机推荐

  1. Android(安卓)Studio快捷键设置成跟Eclip
  2. Android模拟器环境中安装和删除应用程序
  3. 浅谈android的selector,背景选择器
  4. Android中Launcher对于AppWidget处理的分
  5. android 获取uri的正确文件路径的办法
  6. Android(安卓)NDK带来什么
  7. android 手机存储介质大全
  8. Android(安卓)软键盘弹出隐藏挤压界面等
  9. 如何实现android清理后台时,自己的软件不
  10. Android之Action Bar