Android--多点触控的实现


Android多点触控在本质上需要LCD驱动和程序本身设计上支持,目前市面上只要使用电容屏触控原理的手机均可以支持多点触控Multitouch技术,对于网页缩放、手势操作上有更好的用户体验。 在Android平台上事件均使用了MotionEvent对象方式处理,比如开始触控时会触发ACTION_DOWN而移动操作时为 ACTION_MOVE最终放开手指时触发ACTION_UP事件。当然还有用户无规则的操作可能触发ACTION_CANCEL这个动作.

对于常规的控件触控操作在内部为View的setOnTouchListener()接口实现的 onTouchEvent()方法来处理。

下面用ImageView做演示:


                           

main.xml:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <FrameLayout  
  3. xmlns:android="http://schemas.android.com/apk/res/android"  
  4. android:layout_width="fill_parent"  
  5. android:layout_height="fill_parent" >  
  6. <ImageView android:id="@+id/imageView"  
  7. android:layout_width="fill_parent"  
  8. android:layout_height="fill_parent"  
  9. android:src="@drawable/pic"  
  10. android:scaleType="matrix" >  
  11. </ImageView>  
  12. </FrameLayout>  

要注意的是 android:scaleType 的属性必须设置为matrix,否则图片无法改变大小。

java文件:

  1. package com.shao.muti;  
  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.Log;  
  8. import android.view.MotionEvent;  
  9. import android.view.View;  
  10. import android.view.View.OnTouchListener;  
  11. import android.widget.ImageView;  
  12.   
  13. public class MutiTouchActivity extends Activity implements OnTouchListener{  
  14.     /** Called when the activity is first created. */  
  15.     private static final String TAG="Touch";  
  16.     private static final int NONE= 0 ;  
  17.     private static final int DRAG = 1;  
  18.     private static final int ZOOM =2;  
  19.     int mode  = NONE;  
  20.     Matrix matrix = new Matrix();  
  21.     Matrix savedMatrix =  new Matrix();  
  22.       
  23.     PointF start = new PointF();  
  24.     PointF mid = new PointF();  
  25.     float oldDist = 1f;  
  26.       
  27.     @Override  
  28.     public void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.main);  
  31.         ImageView view = (ImageView) findViewById(R.id.imageView);  
  32.         view.setOnTouchListener(this);  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean onTouch(View v, MotionEvent event) {  
  37.         // TODO Auto-generated method stub   
  38.         ImageView view = (ImageView) v;  
  39.         printEventinfo(event);//测试输出信息   
  40.         switch(event.getAction()&MotionEvent.ACTION_MASK)  
  41.         {  
  42.         case MotionEvent.ACTION_DOWN:  
  43.             savedMatrix.set(matrix);  
  44.                //設置初始點位置   
  45.             start.set(event.getX(),event.getY());  
  46.             Log.d(TAG,"mode=DRAG");  
  47.             mode  =DRAG;  
  48.             break;  
  49.         case MotionEvent.ACTION_POINTER_1_DOWN:  
  50.             oldDist= spacing(event);  
  51.             Log.d(TAG,"lodDist="+oldDist);  
  52.             if(oldDist>10f){  
  53.                 savedMatrix.set(matrix);  
  54.                 midPoint(mid,event);  
  55.                 mode = ZOOM;  
  56.                 Log.d(TAG,"mode=ZOOM");  
  57.                   
  58.             }  
  59.             break;  
  60.         case MotionEvent.ACTION_UP:  
  61.         case MotionEvent.ACTION_POINTER_1_UP:  
  62.             mode  =NONE;  
  63.             Log.d(TAG,"mode=NONE");  
  64.             break;  
  65.         case MotionEvent.ACTION_MOVE:  
  66.             if(mode==DRAG){  
  67.                 matrix.set(savedMatrix);  
  68.                 matrix.postTranslate(event.getX()-start.x, event.getY()-start.y);  
  69.             }  
  70.             else if(mode == ZOOM){  
  71.                  float newDist = spacing(event);  
  72.                     Log.d(TAG, "newDist=" + newDist);  
  73.                     if (newDist > 10f) {  
  74.                        matrix.set(savedMatrix);  
  75.                        float scale = newDist / oldDist;  
  76.                        matrix.postScale(scale, scale, mid.x, mid.y);  
  77.                     }  
  78.                  }  
  79.             break;  
  80.         }  
  81.         view.setImageMatrix(matrix);  
  82.         return true;  
  83.           
  84.     }  
  85.     private void printEventinfo(MotionEvent event){  
  86.         int num =0;  
  87.         System.out.println("触控动作---->"+event.getAction()); //获取触控动作比如ACTION_DOWN   
  88.         System.out.println("取触控点的数量--->"+event.getPointerCount()); //获取触控点的数量,比如2则可能是两个手指同时按压屏幕   
  89.         num = event.getPointerCount();  
  90.         for(int i=0;i<num;i++){  
  91.             System.out.println("索引-->"+event.getPointerId(i)); //对于每个触控的点的细节,我们可以通过一个循环执行getPointerId方法获取索引   
  92.             System.out.println("第i个触控点的x位置-->"+event.getX(i)); //获取第i个触控点的x位置   
  93.             System.out.println("第i个触控点的y位置-->"+event.getY(i)); //获取第i个点触控的y位置   
  94.             System.out.println("手指压力-->"+event.getPressure(i)); //LCD可以感应出用户的手指压力,当然具体的级别由驱动和物理硬件决定的   
  95.         }  
  96.         System.out.println("开始时间"+event.getDownTime()); //按下开始时间   
  97.         System.out.println(" 事件结束时间"+event.getEventTime()); // 事件结束时间   
  98.         System.out.println("总共按下时花费时间"+(event.getEventTime()-event.getDownTime())); //总共按下时花费时间   
  99.   
  100.     }  
  101.       /** Determine the space between the first two fingers */  
  102.     private float spacing(MotionEvent event){  
  103.         float x = event.getX(0)-event.getY(1);  
  104.         float y = event.getY(0)-event.getY(1);  
  105.         return (float)Math.sqrt(x*x+y*y);  
  106.     }  
  107.     /** Calculate the mid point of the first two fingers */  
  108.        private void midPoint(PointF point, MotionEvent event) {  
  109.           float x = event.getX(0) + event.getX(1);  
  110.           float y = event.getY(0) + event.getY(1);  
  111.           point.set(x / 2, y / 2);  
  112.        }  
  113. }  

相关内容