我们在使用应用当中经常需要浏览图片,比如在微信当中,点击图片之后可以对图片进行缩放。
本博客介绍如何对图片进行拖拽和缩放,这首先要了解Android中的触摸机制了,在屏幕中有手指按下、手指抬起、手指移动还有多个手指触摸的动作。我们要实现对图片的拖拽和缩放就是要基于这些动作来进行逻辑处理。
图片的拖拽主要是计算手指开始的位置与当前手指的位置关系,来进行平移的,具体可以看代码。
图片的缩放就涉及到计算两点之间的距离来得到缩放比,调用矩阵方法来达到缩放的效果。
1. package com.wwj.dragscale;
2.
3. import android.app.Activity;
4. import android.graphics.Matrix;
5. import android.graphics.PointF;
6. import android.os.Bundle;
7. import android.util.FloatMath;
8. import android.view.MotionEvent;
9. import android.view.View;
10. import android.view.View.OnTouchListener;
11. import android.widget.ImageView;
12.
13. /**
14. * 对图片进行拖拽和缩放
15. *
16. * @author wwj
17. *
18. */
19. public class MainActivity extends Activity {
20. private ImageView imageView;
21.
22. @Override
23. protected void onCreate(Bundle savedInstanceState) {
24. super.onCreate(savedInstanceState);
25. setContentView(R.layout.activity_main);
26. imageView = (ImageView) findViewById(R.id.imageView);
27. new TouchListener());
28. }
29.
30. private class TouchListener implements OnTouchListener {
31.
32. private PointF startPoint = new PointF();
33. private Matrix matrix = new Matrix();
34. private Matrix currentMaritx = new Matrix();
35.
36. private int mode = 0; // 用于标记模式
37. private static final int DRAG = 1; // 拖动
38. private static final int ZOOM = 2; // 放大
39. private float startDis = 0;
40. private PointF midPoint; // 中心点
41.
42. @Override
43. public boolean onTouch(View v, MotionEvent event) {
44. switch (event.getAction() & MotionEvent.ACTION_MASK) {
45. case MotionEvent.ACTION_DOWN:
46. // 拖拽
47. // 记录ImageView当前移动位置
48. // 开始点
49. break;
50. case MotionEvent.ACTION_MOVE:// 移动事件
51. if (mode == DRAG) { // 图片拖动事件
52. float dx = event.getX() - startPoint.x; // x轴移动距离
53. float dy = event.getY() - startPoint.y;
54. // 在当前的位置基础上移动
55. matrix.postTranslate(dx, dy);
56. else if (mode == ZOOM) { // 图片放大事件
57. float endDis = distance(event); // 结束距离
58. if (endDis > 10f) {
59. float scale = endDis / startDis; // 放大倍数
60. matrix.set(currentMaritx);
61. matrix.postScale(scale, scale, midPoint.x, midPoint.y);
62. }
63.
64. }
65. break;
66. case MotionEvent.ACTION_UP:
67. 0;
68. break;
69. // 有手指离开屏幕,但屏幕还有触点(手指)
70. case MotionEvent.ACTION_POINTER_UP:
71. 0;
72. break;
73. // 当屏幕上已经有触点(手指),再有一个手指压下屏幕
74. case MotionEvent.ACTION_POINTER_DOWN:
75. mode = ZOOM;
76. startDis = distance(event);
77. if (startDis > 10f) { // 避免手指上有两个
78. midPoint = mid(event);
79. // 记录当前的缩放倍数
80. }
81. break;
82. }
83. // 显示缩放后的图片
84. imageView.setImageMatrix(matrix);
85. return true;
86. }
87.
88. }
89.
90. /**
91. * 计算两点之间的距离
92. *
93. * @param event
94. * @return
95. */
96. public static float distance(MotionEvent event) {
97. float dx = event.getX(1) - event.getX(0);
98. float dy = event.getY(1) - event.getY(0);
99. return FloatMath.sqrt(dx * dx + dy * dy);
100. }
101.
102. /**
103. * 计算两点之间的中间点
104. *
105. * @param event
106. * @return
107. */
108. public static PointF mid(MotionEvent event) {
109. float midX = (event.getX(1) + event.getX(0)) / 2;
110. float midY = (event.getY(1) + event.getY(0)) / 2;
111. return new PointF(midX, midY);
112. }
113.
114. }