/[caddi]/CaddiPictureUpload/trunk/app/src/main/java/com/caddi/android/caddipictureupload/ZoomableImageView.java
ViewVC logotype

Contents of /CaddiPictureUpload/trunk/app/src/main/java/com/caddi/android/caddipictureupload/ZoomableImageView.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download)
Mon Jul 27 06:41:43 2015 UTC (8 years, 10 months ago) by torben
File size: 10445 byte(s)
First import
1 package com.caddi.android.caddipictureupload;
2
3 import android.content.Context;
4 import android.graphics.Bitmap;
5 import android.graphics.Matrix;
6 import android.graphics.PointF;
7 import android.util.AttributeSet;
8 import android.view.MotionEvent;
9 import android.view.ScaleGestureDetector;
10 import android.view.View;
11 import android.widget.ImageView;
12
13 /**
14 * Copied from http://stackoverflow.com/questions/6650398/android-imageview-zoom-in-and-zoom-out
15 */
16 public class ZoomableImageView extends ImageView
17 {
18 Matrix matrix = new Matrix();
19
20 static final int NONE = 0;
21 static final int DRAG = 1;
22 static final int ZOOM = 2;
23 static final int CLICK = 3;
24 int mode = NONE;
25
26 PointF last = new PointF();
27 PointF start = new PointF();
28 float minScale = 1f;
29 float maxScale = 4f;
30 float[] m;
31
32 float redundantXSpace, redundantYSpace;
33 float width, height;
34 float saveScale = 1f;
35 float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
36
37 ScaleGestureDetector mScaleDetector;
38 Context context;
39
40 public ZoomableImageView(Context context, AttributeSet attr)
41 {
42 super(context, attr);
43 super.setClickable(true);
44 this.context = context;
45 mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
46 matrix.setTranslate(1f, 1f);
47 m = new float[9];
48 setImageMatrix(matrix);
49 setScaleType(ScaleType.MATRIX);
50
51 setOnTouchListener(new OnTouchListener()
52 {
53
54 @Override
55 public boolean onTouch(View v, MotionEvent event)
56 {
57 mScaleDetector.onTouchEvent(event);
58
59 matrix.getValues(m);
60 float x = m[Matrix.MTRANS_X];
61 float y = m[Matrix.MTRANS_Y];
62 PointF curr = new PointF(event.getX(), event.getY());
63
64 switch (event.getAction())
65 {
66 //when one finger is touching
67 //set the mode to DRAG
68 case MotionEvent.ACTION_DOWN:
69 last.set(event.getX(), event.getY());
70 start.set(last);
71 mode = DRAG;
72 break;
73 //when two fingers are touching
74 //set the mode to ZOOM
75 case MotionEvent.ACTION_POINTER_DOWN:
76 last.set(event.getX(), event.getY());
77 start.set(last);
78 mode = ZOOM;
79 break;
80 //when a finger moves
81 //If mode is applicable move image
82 case MotionEvent.ACTION_MOVE:
83 //if the mode is ZOOM or
84 //if the mode is DRAG and already zoomed
85 if (mode == ZOOM || (mode == DRAG && saveScale > minScale))
86 {
87 float deltaX = curr.x - last.x;// x difference
88 float deltaY = curr.y - last.y;// y difference
89 float scaleWidth = Math.round(origWidth * saveScale);// width after applying current scale
90 float scaleHeight = Math.round(origHeight * saveScale);// height after applying current scale
91 //if scaleWidth is smaller than the views width
92 //in other words if the image width fits in the view
93 //limit left and right movement
94 if (scaleWidth < width)
95 {
96 deltaX = 0;
97 if (y + deltaY > 0)
98 deltaY = -y;
99 else if (y + deltaY < -bottom)
100 deltaY = -(y + bottom);
101 }
102 //if scaleHeight is smaller than the views height
103 //in other words if the image height fits in the view
104 //limit up and down movement
105 else if (scaleHeight < height)
106 {
107 deltaY = 0;
108 if (x + deltaX > 0)
109 deltaX = -x;
110 else if (x + deltaX < -right)
111 deltaX = -(x + right);
112 }
113 //if the image doesnt fit in the width or height
114 //limit both up and down and left and right
115 else
116 {
117 if (x + deltaX > 0)
118 deltaX = -x;
119 else if (x + deltaX < -right)
120 deltaX = -(x + right);
121
122 if (y + deltaY > 0)
123 deltaY = -y;
124 else if (y + deltaY < -bottom)
125 deltaY = -(y + bottom);
126 }
127 //move the image with the matrix
128 matrix.postTranslate(deltaX, deltaY);
129 //set the last touch location to the current
130 last.set(curr.x, curr.y);
131 }
132 break;
133 //first finger is lifted
134 case MotionEvent.ACTION_UP:
135 mode = NONE;
136 int xDiff = (int) Math.abs(curr.x - start.x);
137 int yDiff = (int) Math.abs(curr.y - start.y);
138 if (xDiff < CLICK && yDiff < CLICK)
139 performClick();
140 break;
141 // second finger is lifted
142 case MotionEvent.ACTION_POINTER_UP:
143 mode = NONE;
144 break;
145 }
146 setImageMatrix(matrix);
147 invalidate();
148 return true;
149 }
150
151 });
152 }
153
154 @Override
155 public void setImageBitmap(Bitmap bm)
156 {
157 super.setImageBitmap(bm);
158 bmWidth = bm.getWidth();
159 bmHeight = bm.getHeight();
160 }
161
162 public void setMaxZoom(float x)
163 {
164 maxScale = x;
165 }
166
167 private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
168 {
169
170 @Override
171 public boolean onScaleBegin(ScaleGestureDetector detector)
172 {
173 mode = ZOOM;
174 return true;
175 }
176
177 @Override
178 public boolean onScale(ScaleGestureDetector detector)
179 {
180 float mScaleFactor = detector.getScaleFactor();
181 float origScale = saveScale;
182 saveScale *= mScaleFactor;
183 if (saveScale > maxScale)
184 {
185 saveScale = maxScale;
186 mScaleFactor = maxScale / origScale;
187 }
188 else if (saveScale < minScale)
189 {
190 saveScale = minScale;
191 mScaleFactor = minScale / origScale;
192 }
193 right = width * saveScale - width - (2 * redundantXSpace * saveScale);
194 bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
195 if (origWidth * saveScale <= width || origHeight * saveScale <= height)
196 {
197 matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
198 if (mScaleFactor < 1)
199 {
200 matrix.getValues(m);
201 float x = m[Matrix.MTRANS_X];
202 float y = m[Matrix.MTRANS_Y];
203 if (mScaleFactor < 1)
204 {
205 if (Math.round(origWidth * saveScale) < width)
206 {
207 if (y < -bottom)
208 matrix.postTranslate(0, -(y + bottom));
209 else if (y > 0)
210 matrix.postTranslate(0, -y);
211 }
212 else
213 {
214 if (x < -right)
215 matrix.postTranslate(-(x + right), 0);
216 else if (x > 0)
217 matrix.postTranslate(-x, 0);
218 }
219 }
220 }
221 }
222 else
223 {
224 matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
225 matrix.getValues(m);
226 float x = m[Matrix.MTRANS_X];
227 float y = m[Matrix.MTRANS_Y];
228 if (mScaleFactor < 1) {
229 if (x < -right)
230 matrix.postTranslate(-(x + right), 0);
231 else if (x > 0)
232 matrix.postTranslate(-x, 0);
233 if (y < -bottom)
234 matrix.postTranslate(0, -(y + bottom));
235 else if (y > 0)
236 matrix.postTranslate(0, -y);
237 }
238 }
239 return true;
240 }
241 }
242
243 @Override
244 protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
245 {
246 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
247 width = View.MeasureSpec.getSize(widthMeasureSpec);
248 height = View.MeasureSpec.getSize(heightMeasureSpec);
249 //Fit to screen.
250 float scale;
251 float scaleX = width / bmWidth;
252 float scaleY = height / bmHeight;
253 scale = Math.min(scaleX, scaleY);
254 matrix.setScale(scale, scale);
255 setImageMatrix(matrix);
256 saveScale = 1f;
257
258 // Center the image
259 redundantYSpace = height - (scale * bmHeight) ;
260 redundantXSpace = width - (scale * bmWidth);
261 redundantYSpace /= 2;
262 redundantXSpace /= 2;
263
264 matrix.postTranslate(redundantXSpace, redundantYSpace);
265
266 origWidth = width - 2 * redundantXSpace;
267 origHeight = height - 2 * redundantYSpace;
268 right = width * saveScale - width - (2 * redundantXSpace * saveScale);
269 bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
270 setImageMatrix(matrix);
271 }
272 }

  ViewVC Help
Powered by ViewVC 1.1.20