Advertisement
Guest User

Untitled

a guest
Jul 25th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.29 KB | None | 0 0
  1. package info.kimjihyok.customviewtestproject;
  2.  
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Matrix;
  6. import android.graphics.PointF;
  7. import android.util.AttributeSet;
  8. import android.view.MotionEvent;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11.  
  12. public class ZoomableViewGroup extends ViewGroup {
  13. // Constants for MAX, MIN zoom
  14. private static final int MAX_ZOOM = 2;
  15. private static final int MIN_ZOOM = 1;
  16.  
  17. private static float MAX_TRANS_X;
  18. private static float MAX_TRANS_Y;
  19. private static float MIN_TRANS_X;
  20. private static float MIN_TRANS_Y;
  21.  
  22. // these matrices will be used to zoom image
  23. private Matrix matrix = new Matrix();
  24. private Matrix matrixInverse = new Matrix();
  25. private Matrix savedMatrix = new Matrix();
  26.  
  27. // we can be in one of these 2 states
  28. private static final int NONE = 0;
  29. private static final int ZOOM = 1;
  30.  
  31. private int mode = NONE;
  32.  
  33.  
  34. // remember some things for zooming
  35. private PointF start = new PointF();
  36. private PointF mid = new PointF();
  37.  
  38. private float oldDist = 1f;
  39. private float[] lastEvent = null;
  40. private float[] mDispatchTouchEventWorkingArray = new float[2];
  41. private float[] mOnTouchEventWorkingArray = new float[2];
  42.  
  43. @Override
  44. public boolean dispatchTouchEvent(MotionEvent ev) {
  45. mDispatchTouchEventWorkingArray[0] = ev.getX();
  46. mDispatchTouchEventWorkingArray[1] = ev.getY();
  47. mDispatchTouchEventWorkingArray = screenPointsToScaledPoints(mDispatchTouchEventWorkingArray);
  48. ev.setLocation(mDispatchTouchEventWorkingArray[0],
  49. mDispatchTouchEventWorkingArray[1]);
  50. return super.dispatchTouchEvent(ev);
  51. }
  52.  
  53. private float[] scaledPointsToScreenPoints(float[] a) {
  54. matrix.mapPoints(a);
  55. return a;
  56. }
  57.  
  58. private float[] screenPointsToScaledPoints(float[] a){
  59. matrixInverse.mapPoints(a);
  60. return a;
  61. }
  62.  
  63. public ZoomableViewGroup(Context context) {
  64. super(context);
  65. init(context);
  66. }
  67.  
  68. public ZoomableViewGroup(Context context, AttributeSet attrs) {
  69. super(context, attrs);
  70. init(context);
  71. }
  72.  
  73. public ZoomableViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
  74. super(context, attrs, defStyleAttr);
  75. init(context);
  76. }
  77.  
  78. /**
  79. * Determine the space between the first two fingers
  80. */
  81. private float spacing(MotionEvent event) {
  82. try {
  83. float x = event.getX(0) - event.getX(1);
  84. float y = event.getY(0) - event.getY(1);
  85. return (float)Math.sqrt(x * x + y * y);
  86. } catch (Exception e) {
  87. // It is a drag, do nothing
  88. return 0;
  89. }
  90. }
  91.  
  92. /**
  93. * Calculate the mid point of the first two fingers
  94. */
  95. private void midPoint(PointF point, MotionEvent event) {
  96. float x = event.getX(0) + event.getX(1);
  97. float y = event.getY(0) + event.getY(1);
  98. point.set(x / 2, y / 2);
  99. }
  100.  
  101.  
  102. private void init(Context context){
  103.  
  104. }
  105.  
  106.  
  107. @Override
  108. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  109. int childCount = getChildCount();
  110. for (int i = 0; i < childCount; i++) {
  111. View child = getChildAt(i);
  112. if (child.getVisibility() != GONE) {
  113. child.layout(l, t, l+child.getMeasuredWidth(), t + child.getMeasuredHeight());
  114. }
  115. }
  116. }
  117.  
  118. @Override
  119. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  120. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  121.  
  122. float[] values = new float[9];
  123. matrix.getValues(values);
  124.  
  125. int childCount = getChildCount();
  126. for (int i = 0; i < childCount; i++) {
  127. View child = getChildAt(i);
  128. if (child.getVisibility() != GONE) {
  129. measureChild(child, widthMeasureSpec, heightMeasureSpec);
  130. }
  131. }
  132.  
  133. }
  134.  
  135. @Override
  136. protected void dispatchDraw(Canvas canvas) {
  137. // factor 2: max matrix: [scale, 0, scale * width - width], [0, scale, scale * height - height], [0, 0, 1.0]
  138. // factor 2: min matrix: [scale, 0, (scale * width - width) * -1], [0, scale, (scale * height - height) * -1], [0, 0, 1.0]
  139.  
  140. float[] values = new float[9];
  141. matrix.getValues(values);
  142.  
  143.  
  144. // set max trans x, y values according to scale value
  145. // max matrix: [scale, 0, scale * width - width], [0, scale, scale * height - height], [0, 0, 1.0]
  146. // min matrix: [scale, 0, (scale * width - width) * -1], [0, scale, (scale * height - height) * -1], [0, 0, 1.0]
  147. MAX_TRANS_X = (values[Matrix.MSCALE_X] * getWidth()) - getWidth();
  148. MAX_TRANS_Y = (values[Matrix.MSCALE_X] * getHeight()) - getHeight();
  149. MIN_TRANS_X = ((values[Matrix.MSCALE_X] * getWidth()) - getWidth()) * -1;
  150. MIN_TRANS_Y = ((values[Matrix.MSCALE_X] * getHeight()) - getHeight()) * -1;
  151.  
  152. // Log.d("dispatchDraw", "MIN MAX: " + "[" + MIN_TRANS_X + ", " + MAX_TRANS_X + "] [" + MIN_TRANS_Y + ", " + MAX_TRANS_Y + "]");
  153. // Log.d("dispatchDraw", matrix.toShortString());
  154.  
  155. // limit transformation matrix value
  156. if (values[Matrix.MTRANS_X] > MAX_TRANS_X) {
  157. values[Matrix.MTRANS_X] = MAX_TRANS_X;
  158. }
  159. if (values[Matrix.MTRANS_Y] > MAX_TRANS_Y) {
  160. values[Matrix.MTRANS_X] = MAX_TRANS_X;
  161. }
  162. if (values[Matrix.MTRANS_X] < MIN_TRANS_X) {
  163. values[Matrix.MTRANS_X] = MIN_TRANS_X;
  164. }
  165. if (values[Matrix.MTRANS_X] < MIN_TRANS_Y) {
  166. values[Matrix.MTRANS_X] = MIN_TRANS_Y;
  167. }
  168.  
  169. matrix.setValues(values);
  170. // Log.d("dispatchDraw", matrix.toShortString());
  171.  
  172. canvas.save();
  173. canvas.setMatrix(matrix);
  174. super.dispatchDraw(canvas);
  175. canvas.restore();
  176. }
  177.  
  178. @Override
  179. public boolean onTouchEvent(MotionEvent event) {
  180. // handle touch events here
  181. mOnTouchEventWorkingArray[0] = event.getX();
  182. mOnTouchEventWorkingArray[1] = event.getY();
  183.  
  184. mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray);
  185.  
  186. event.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]);
  187.  
  188. switch (event.getAction() & MotionEvent.ACTION_MASK) {
  189. case MotionEvent.ACTION_DOWN:
  190. savedMatrix.set(matrix);
  191. start.set(event.getX(), event.getY());
  192. mode = ZOOM;
  193. lastEvent = null;
  194. break;
  195. case MotionEvent.ACTION_POINTER_DOWN:
  196. oldDist = spacing(event);
  197. if (oldDist > 10f) {
  198. savedMatrix.set(matrix);
  199. midPoint(mid, event);
  200. mode = ZOOM;
  201. }
  202. lastEvent = new float[4];
  203. lastEvent[0] = event.getX(0);
  204. lastEvent[1] = event.getX(1);
  205. lastEvent[2] = event.getY(0);
  206. lastEvent[3] = event.getY(1);
  207. break;
  208. case MotionEvent.ACTION_UP:
  209. case MotionEvent.ACTION_POINTER_UP:
  210. mode = NONE;
  211. lastEvent = null;
  212. break;
  213. case MotionEvent.ACTION_MOVE:
  214. if (mode == ZOOM) {
  215. matrix.set(savedMatrix);
  216.  
  217. float newDist = spacing(event);
  218. if (newDist > 10f) {
  219. matrix.set(savedMatrix);
  220. float scale = (newDist / oldDist);
  221.  
  222. float[] values = new float[9];
  223. matrix.getValues(values);
  224.  
  225. // limit scale matrix value
  226. float totalZoomedScale = scale * values[Matrix.MSCALE_X];
  227. if(totalZoomedScale >= MAX_ZOOM) {
  228. scale = MAX_ZOOM / values[Matrix.MSCALE_X];
  229. } else if (totalZoomedScale <= MIN_ZOOM) {
  230. scale = MIN_ZOOM / values[Matrix.MSCALE_X];
  231. }
  232.  
  233.  
  234. matrix.postScale(scale, scale, mid.x, mid.y);
  235. matrix.invert(matrixInverse);
  236. }
  237. }
  238. break;
  239. }
  240.  
  241. invalidate();
  242. return true;
  243. }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement