Android学习之多点触摸并不神秘

时间:2023-03-09 09:02:32
Android学习之多点触摸并不神秘

最近研究了一下多点触摸,写了个利用多点触摸来控制图片大小和单点触摸控制图片移动的程序,和大家分享分享。

Android中监听触摸事件是onTouchEvent方法,它的参数为MotionEvent,下面列举MotionEvent的一些常用的方法:

getPointerCount() 获得触屏的点数。

getX() 获得触屏的X坐标值

getY() 获得触屏的Y坐标值

getAction() 获得触屏的动作

ACTION_DOWN:按下的动作开始,比如用手指按屏幕。

ACTION_UP:按下的动作完成,比如手指停止按屏幕,离开屏幕。

ACTION_MOVE:在动作开始和完成之间的移动,比如手指在屏幕上滑动。

还介绍下程序中用到的ImageView,ImageView.setFrame()的四个参数指的是left,top,right,bottom如图:

Android学习之多点触摸并不神秘

left和top指的就是ImageView左上角的坐标x和y,right,bottom指的就是ImageView的右下角的坐标x和y了。

接下来看程序,程序中有详细的介绍:

  1. package com.practice.imageviewpic;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.*;
  5. import android.graphics.drawable.BitmapDrawable;
  6. import android.os.Bundle;
  7. import android.view.MotionEvent;
  8. import android.widget.ImageView;
  9. import android.widget.ImageView.ScaleType;
  10. public class ImageViewPic extends Activity {
  11. /*
  12. * 利用多点触控来控制ImageView中图像的放大与缩小
  13. * 手指控制图片移动
  14. */
  15. private MyImageView imageView;
  16. private Bitmap bitmap;
  17. //两点触屏后之间的长度
  18. private float beforeLenght;
  19. private float afterLenght;
  20. //单点移动的前后坐标值
  21. private float afterX,afterY;
  22. private float beforeX,beforeY;
  23. /** Called when the activity is first created. */
  24. @Override
  25. public void onCreate(Bundle savedInstanceState) {
  26. super.onCreate(savedInstanceState);
  27. findView();
  28. setContentView(imageView);
  29. config();
  30. }
  31. private void findView() {
  32. imageView = new MyImageView(this);
  33. //获得图片
  34. bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.xing)).getBitmap();
  35. }
  36. private void config() {
  37. //设置imageView的显示图片
  38. imageView.setImageBitmap(bitmap);
  39. //设置图片填充ImageView
  40. imageView.setScaleType(ScaleType.FIT_XY);
  41. }
  42. //创建一个自己的ImageView类
  43. class MyImageView extends ImageView {
  44. private float scale = 0.1f;
  45. public MyImageView(Context context) {
  46. super(context);
  47. }
  48. //用来设置ImageView的位置
  49. private void setLocation(int x,int y) {
  50. this.setFrame(this.getLeft()+x, this.getTop()+y, this.getRight()+x, this.getBottom()+y);
  51. }
  52. /*
  53. * 用来放大缩小ImageView
  54. * 因为图片是填充ImageView的,所以也就有放大缩小图片的效果
  55. * flag为0是放大图片,为1是小于图片
  56. */
  57. private void setScale(float temp,int flag) {
  58. if(flag==0) {
  59. this.setFrame(this.getLeft()-(int)(temp*this.getWidth()),
  60. this.getTop()-(int)(temp*this.getHeight()),
  61. this.getRight()+(int)(temp*this.getWidth()),
  62. this.getBottom()+(int)(temp*this.getHeight()));
  63. }else {
  64. this.setFrame(this.getLeft()+(int)(temp*this.getWidth()),
  65. this.getTop()+(int)(temp*this.getHeight()),
  66. this.getRight()-(int)(temp*this.getWidth()),
  67. this.getBottom()-(int)(temp*this.getHeight()));
  68. }
  69. }
  70. //绘制边框
  71. @Override
  72. protected void onDraw(Canvas canvas) {
  73. super.onDraw(canvas);
  74. Rect rec=canvas.getClipBounds();
  75. rec.bottom--;
  76. rec.right--;
  77. Paint paint=new Paint();
  78. paint.setColor(Color.RED);
  79. paint.setStyle(Paint.Style.STROKE);
  80. canvas.drawRect(rec, paint);
  81. }
  82. /* 让图片跟随手指触屏的位置移动
  83. * beforeX、Y是用来保存前一位置的坐标
  84. * afterX、Y是用来保存当前位置的坐标
  85. * 它们的差值就是ImageView各坐标的增加或减少值
  86. */
  87. public void moveWithFinger(MotionEvent event) {
  88. switch(event.getAction()) {
  89. case MotionEvent.ACTION_DOWN:
  90. beforeX = event.getX();
  91. beforeY = event.getY();
  92. break;
  93. case MotionEvent.ACTION_MOVE:
  94. afterX = event.getX();
  95. afterY = event.getY();
  96. this.setLocation((int)(afterX-beforeX),(int)(afterY-beforeY));
  97. beforeX = afterX;
  98. beforeY = afterY;
  99. break;
  100. case MotionEvent.ACTION_UP:
  101. break;
  102. }
  103. }
  104. /*
  105. * 通过多点触屏放大或缩小图像
  106. * beforeLenght用来保存前一时间两点之间的距离
  107. * afterLenght用来保存当前时间两点之间的距离
  108. */
  109. public void scaleWithFinger(MotionEvent event) {
  110. float moveX = event.getX(1) - event.getX(0);
  111. float moveY = event.getY(1) - event.getY(0);
  112. switch(event.getAction()) {
  113. case MotionEvent.ACTION_DOWN:
  114. beforeLenght = (float) Math.sqrt( (moveX*moveX) + (moveY*moveY) );
  115. break;
  116. case MotionEvent.ACTION_MOVE:
  117. //得到两个点之间的长度
  118. afterLenght = (float) Math.sqrt( (moveX*moveX) + (moveY*moveY) );
  119. float gapLenght = afterLenght - beforeLenght;
  120. if(gapLenght == 0) {
  121. break;
  122. }
  123. //如果当前时间两点距离大于前一时间两点距离,则传0,否则传1
  124. if(gapLenght>0) {
  125. this.setScale(scale,0);
  126. }else {
  127. this.setScale(scale,1);
  128. }
  129. beforeLenght = afterLenght;
  130. break;
  131. }
  132. }
  133. }
  134. //这里来监听屏幕触控时间
  135. @Override
  136. public boolean onTouchEvent(MotionEvent event) {
  137. /*
  138. * 判定用户是否触摸到了图片
  139. * 如果是单点触摸则调用控制图片移动的方法
  140. * 如果是2点触控则调用控制图片大小的方法
  141. */
  142. if(event.getY() > imageView.getTop() && event.getY() < imageView.getBottom()
  143. && event.getX() > imageView.getLeft() && event.getX() < imageView.getRight()) {
  144. if(event.getPointerCount() == 2) {
  145. imageView.scaleWithFinger(event);
  146. }else if(event.getPointerCount() == 1) {
  147. imageView.moveWithFinger(event);
  148. }
  149. }
  150. return true;
  151. }
  152. }

源程序的下载地址为:http://download.csdn.net/source/3281618