Android 移动缩放的ImageView

摘要:
今天我们将介绍如何在Android中缩放和移动ImageView以及自定义TouchImageView。

  今天介绍一下Android中怎么实现ImageView的缩放和移动,自定义TouchImageView。

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

免责声明:文章转载自《Android 移动缩放的ImageView》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Python使用Plotly绘图工具,绘制散点图、线形图简单演示 Oracle 数据库并发导致段级锁(表级锁)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android 图片设置圆角 方法之二

Android中经常会遇到对图片进行二次处理,例如加圆角,或者显示圆形图片。接下来我们再介绍一种方法。 首先, 自定义ImageView: android:id="@+id/iv" android:layout_width="300dp" android:layout_height="300dp" android:layout_centerHorizont...

eigen Matrix详解

Eigen Matrix 详解 在Eigen中,所有的matrices 和vectors 都是模板类Matrix 的对象,Vectors 只是一种特殊的矩阵,行或者列为1. Matrix的前三个模板参数 Matrix 类有6个模板参数,现在我们了解前三个足够。剩下的三个参数都有默认值,后面会探讨,现在不管他。Matrix 的三个强制的模板参数: Matri...

混淆矩阵(Confusion matrix)的原理及使用(scikit-learn 和 tensorflow)

原理   在机器学习中, 混淆矩阵是一个误差矩阵, 常用来可视化地评估监督学习算法的性能. 混淆矩阵大小为 (n_classes, n_classes) 的方阵, 其中 n_classes 表示类的数量. 这个矩阵的每一行表示真实类中的实例, 而每一列表示预测类中的实例 (Tensorflow 和 scikit-learn 采用的实现方式). 也可以是,...

android绘图—Paint path 旋转

http://meteor6789.blog.163.com/blog/static/35040733201111193535153/ Piant 看一段代码: mPaint = new Paint();mPaint.setAntiAlias(true);//锯齿mPaint.setDither(true);//mPaint.setColor(0xFF3...

图片的放大缩小

布局文件 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_par...

OpenCV实现图像变换(python)-仿射变换原理

一般对图像的变化操作有放大、缩小、旋转等,统称为几何变换,对一个图像的图像变换主要有两大步骤,一是实现空间坐标的转换,就是使图像从初始位置到终止位置的移动。二是使用一个插值的算法完成输出图像的每个像素的灰度值。其中主要的图像变换有:仿射变换、投影变换、极坐标变换。 仿射变换## 二维空间坐标的仿射变换公式: [left( egin{matrix} ove...