多点触碰2

 

前面写了一个Pointer2Draw的小程序。这个程序的神奇之处在于,你永远也别想绘制出任何东西。原因是根本没有所谓 的0x00000107。下面看看如何正确的处理多点触摸,光靠event.getAction()吃饭的时代已经终结了……

(1)获得屏幕上的Pointer的数目:

  1. int pointerCount = event.getPointerCount();  
这个函数具体返回值受到物理设备的限制,我费了很大力气将十个手指放到了我的手机上,得到的结果仍然是8

(2)得到手指的ID:Android提供了两个掩码方便我们操作ACTION_POINTER_ID_MASK 0x0000ff00,ACTION_POINTER_ID_SHIFT   0x00000008。

  1. if(pointerCount>1){  
  2.     pointerId = (action & MotionEvent.ACTION_POINTER_ID_MASK)>>>  
  3.                             MotionEvent.ACTION_POINTER_ID_SHIFT;  
  4. }  
(3)利用ID获得坐标信息:
  1. float x = event.getX(pointerId);//获得第二个手指的坐标   
  2. float y = event.getY(pointerId);  
下面终于可以让Pointer2Draw运行起来了。
  1. public boolean onTouchEvent(MotionEvent event){  
  2.     int pointerCount = event.getPointerCount();  
  3.     int pointerId = 0;  
  4.     int action = event.getAction();  
  5.     if(pointerCount>1){  
  6.         pointerId = (action & MotionEvent.ACTION_POINTER_ID_MASK)>>>  
  7.                                 MotionEvent.ACTION_POINTER_ID_SHIFT;  
  8.     }  
  9.     float x = 0;  
  10.     float y = 0;  
  11.     if(pointerId == 1){  
  12.         x = event.getX(pointerId);  
  13.         y = event.getY(pointerId);  
  14.         canvas.drawPoint(x, y, paint);  
  15.         imgView.invalidate();  
  16.     }  
  17.     return true;  
  18. }  

注意手指的ID是从0开始的,所以第二个手指的ID是1;然而遗憾的是程序只有在第二个手指DOWN和UP时才绘制。当第一个手指不动时,根本没有有效的方法对第二个手指的移动做出反应。然而触摸屏是很敏感的,你发现很难让它不产生ACTION_MOVE。我们利用Android提供的ACTION_MASK 0x000000ff来改善我们的代码:

  1. public class Pointer2DrawActivity extends Activity implements OnTouchListener{  
  2.     /** Called when the activity is first created. */  
  3.     ImageView imgView;  
  4.     Bitmap bitmap;  
  5.     Canvas canvas;  
  6.     Paint paint;  
  7.     @Override  
  8.     public void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.main);  
  11.         imgView = (ImageView)findViewById(R.id.imgView);  
  12.         Display currentDisplay = getWindowManager().getDefaultDisplay();  
  13.         float dw = currentDisplay.getWidth();  
  14.         float dh = currentDisplay.getHeight();  
  15.         bitmap = Bitmap.createBitmap((int)dw, (int)dh, Config.ARGB_8888);  
  16.         canvas = new Canvas(bitmap);  
  17.         paint = new Paint();  
  18.         paint.setColor(Color.GREEN);  
  19.         paint.setStrokeWidth((float10.00);//设置笔刷大小,自己的屏幕太犀利了   
  20.         imgView.setImageBitmap(bitmap);  
  21.         imgView.setOnTouchListener(this);  
  22.     }  
  23.     @Override  
  24.     public boolean onTouch(View v, MotionEvent event) {  
  25.         int pointerCount = event.getPointerCount();  
  26.         int pointerId = 0;  
  27.         int action = (event.getAction()&MotionEvent.ACTION_MASK) % 5;//统一单点和多点   
  28.         switch(action){  
  29.         case MotionEvent.ACTION_DOWN:  
  30.             if(pointerCount>1){  
  31.                 pointerId = (event.getAction()&MotionEvent.ACTION_POINTER_ID_MASK)>>>  
  32.                             MotionEvent.ACTION_POINTER_ID_SHIFT;  
  33.             }  
  34.             break;  
  35.         case MotionEvent.ACTION_MOVE:  
  36.             if(pointerCount == 2){  
  37.                 float x = event.getX(1);  
  38.                 float y = event.getY(1);  
  39.                 canvas.drawPoint((int)x, (int)y, paint);  
  40.                 imgView.invalidate();  
  41.             }  
  42.             break;  
  43.         case MotionEvent.ACTION_UP:  
  44.             break;  
  45.         }  
  46.    
  47.         return true;  
  48.           
  49.     }  
  50. }  
好了,Pointer2Draw终于按照想要的方式运行了。
下面是一个简单的示例代码,实现了继承自UVCCameraTextureView类的多点触碰支持放大缩小和旋转的UVCCamera类: ```java public class UVCCamera extends UVCCameraTextureView { private float mPrevX, mPrevY; private float mScaleFactor = 1f; private float mRotationDegree = 0f; public UVCCamera(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mPrevX = event.getX(0); mPrevY = event.getY(0); break; case MotionEvent.ACTION_MOVE: if (event.getPointerCount() == 1) { float x = event.getX(0); float y = event.getY(0); float dx = x - mPrevX; float dy = y - mPrevY; mRotationDegree += Math.atan2(dy, dx) * 180 / Math.PI; setRotation(mRotationDegree); mPrevX = x; mPrevY = y; } else if (event.getPointerCount() == 2) { float x1 = event.getX(0); float y1 = event.getY(0); float x2 = event.getX(1); float y2 = event.getY(1); float distance = (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); if (distance > 10f) { float scaleFactor = distance / mPrevDistance; mScaleFactor *= scaleFactor; mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); setScaleX(mScaleFactor); setScaleY(mScaleFactor); } float angle = (float) Math.atan2(y2 - y1, x2 - x1) * 180 / (float) Math.PI; setRotation(angle); mPrevDistance = distance; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: break; } return true; } } ``` 这个类继承自UVCCameraTextureView,重写了onTouchEvent方法,实现了多点触碰支持放大缩小和旋转的功能。当手指只有一个触点时,根据手指移动的方向来旋转图像;当手指有两个触点时,根据两个触点之间的距离来缩放图像,并根据两个触点之间的角度来旋转图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值