android多点触摸手势&手势库GestureLibraries

一.手势事件的监听方式

1.使用 onTouchEvent事件监听器或者使用 setOnTouchEventListener监听触摸事件javascript

2.事件类型的判断java

event.getAction()或者event.getActionMask(),注意,前者包含后者,后者判断起来比较精确android

3.事件的生命周期  Action_DOWN(按下) ---> Action_MOVE(移动) --->Action_UP/Action_CANCELED(抬起手指或者滑出屏幕)ide

在一些事件,如Click,LongClick等事件按照该周期的时间长度和 移动位置来决定的测试

4.事件传递的3个阶段ui


第一阶段是  分发/拦截阶段 ondispatchEvent和onInteceptorEvent(通常在此阶段处理事件,可能致使事件没法传递)this

第二阶段是 向下传递阶段 onTouchEventspa


学过javascript的读者可能会发现,这种事件的传递和js的十分相似,不过少了一个阶段就是 目标View处理阶段,按照javascript的划分,code

第一个阶段 捕获阶段(不管如何处理,事件总会传递到目标控件)orm

第二个阶段 目标控件事件处理阶段

第三个阶段 冒泡阶段(这个阶段处理事件的比较多,可终止冒泡)


很显然,android的事件传递阶段彷佛很不友好,由于此阶段捕获致使不少处理冲突,甚至目标控件没法获得事件,好比ViewGroup拦截事件以后,将直接把事件交给本身的onTouchEvent进行处理,形成子View上的事件处理程序一直没法执行,不少时候因为这种事件分发问题致使的错误很是多,所以对于这种问题的处理要务必格外当心,若是遇到这种冲突,通常的作法是 2个联系密切的 View控件分别绑定事件,并调用getParent().requestDisallowInterceptTouchEvent(true),但这种方法也是由局限性的,但愿有更好想法的读者指正一下。  


5.多点触摸事件的处理,对于多点触摸,可使用

event.getPointersCount()或者触摸点的数量,而后经过 event.getX(index) ,event.getY(index)得到触摸点的坐标


public class MultiTouchActivity extends Activity
{

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_multi_touch);
	}

    public boolean onTouchEvent(MotionEvent event)
    {
    	//  ֻ2个手指
    	if(event.getPointerCount() == 2)
    	{
    		if(event.getAction() == MotionEvent.ACTION_MOVE)
    		{
    			int historySize = event.getHistorySize();
    			if(historySize == 0)
    				return true;
    			//第1个手指的Y坐标
    			float currentY1 = event.getY(0);
    			//第1个手指的历史纵坐标 
    			float historyY1 = event.getHistoricalY(0, historySize - 1);
    			//第二个手指的的Y坐标
    			float currentY2 = event.getY(1);
    			//第2个手指的历史纵坐标 
    			float historyY2 = event.getHistoricalY(1,historySize - 1);
    			
    			float distance =  Math.abs(currentY1 - currentY2);
    			float historyDistance = Math.abs(historyY1 - historyY2);
    			
    			if(distance > historyDistance)
    			{
    				Log.d("status", "放大");
    				
    			}
    			else if(distance < historyDistance)
    			{
    				Log.d("status", "缩小");
    			}
    			else
    			{
    				Log.d("status", "平行移动");
    			}
    				
    			
    			
    		}
    	}
    	return true;
    }


}


二.使用手势库

public class DrawGestureTest extends Activity implements OnGesturePerformedListener  
{  
      
    private GestureOverlayView mDrawGestureView;  
    private static GestureLibrary sStore;  
      
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
          
        mDrawGestureView = (GestureOverlayView)findViewById(R.id.gesture);  
          
        //设置手势可多笔画绘制,默认状况为单笔画绘制  
        mDrawGestureView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);  
        //设置手势的颜色(蓝色)  
        mDrawGestureView.setGestureColor(gestureColor(R.color.gestureColor));  
        //设置还没未能造成手势绘制是的颜色(红色)  
        mDrawGestureView.setUncertainGestureColor(gestureColor(R.color.ungestureColor));  
        //设置手势的粗细  
        mDrawGestureView.setGestureStrokeWidth(4);  
        /*手势绘制完成后淡出屏幕的时间间隔,即绘制完手指离开屏幕后相隔多长时间手势从屏幕上消失; 
         * 能够理解为手势绘制完成手指离开屏幕后到调用onGesturePerformed的时间间隔 
         * 默认值为420毫秒,这里设置为0.5秒 
         */  
        mDrawGestureView.setFadeOffset(500);  
          
        //绑定监听器  
        mDrawGestureView.addOnGesturePerformedListener(this);  
        //建立保存手势的手势库  
        createStore();  
    }  
      
    private void createStore()  
    {  
        File mStoreFile = null;   
        /*判断mStoreFile是为空。 
         * 判断手机是否插入SD卡,而且应用程序是否具备访问SD卡的权限 
         */  
        if (mStoreFile == null && Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))  
        {  
            mStoreFile = new File(Environment.getExternalStorageDirectory(), "mygesture");  
        }   
          
        if (sStore == null)  
        {  
            /* 另外三种建立保存手势文件的方式以下: 
            //保存手势的文件在手机SD卡中 
            sStore = GestureLibraries.fromFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "mygesture"); 
            sStore = GestureLibraries.fromPrivateFile(this, Environment.getExternalStorageDirectory().getAbsolutePath + "mygesture"); 
            //保存手势的文件在应用程序的res/raw文件下 
            sStore = GestureLibraries.fromRawResource(this, R.raw.gestures); 
            */    
            sStore = GestureLibraries.fromFile(mStoreFile);  
        }  
        testLoad();  
    }  
      
    //测试保存手势的文件是否建立成功  
    private void testLoad()  
    {  
        if (sStore.load())  
        {  
            showMessage("手势文件装载成功");  
        }  
        else  
        {  
            showMessage("手势文件装载失败");  
        }  
    }  
      
    public static GestureLibrary getStore()  
    {  
        return sStore;  
    }  
      
    //手势绘制完成时调用  
    @Override  
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture)   
    {  
        // TODO Auto-generated method stub  
        creatDialog(gesture);  
    }  
      
    private void creatDialog(final Gesture gesture)  
    {  
        View dialogView = getLayoutInflater().inflate(R.layout.show_gesture, null);  
        //imageView用于显示绘制的手势  
        ImageView imageView = (ImageView) dialogView.findViewById(R.id.show);  
        //获取用户保存手势的名字  
        EditText editText = (EditText)dialogView.findViewById(R.id.name);  
        final String name = editText.getText().toString();  
        // 调用Gesture的toBitmap方法造成对应手势的位图  
        final Bitmap bitmap = gesture.toBitmap(128, 128, 10, gestureColor(R.color.showColor));  
        imageView.setImageBitmap(bitmap);  
          
        Builder dialogBuider = new AlertDialog.Builder(DrawGestureTest.this);  
        dialogBuider.setView(dialogView);  
        //绑定对话框的确认按钮监听事件  
        dialogBuider.setPositiveButton(  
                "保存", new OnClickListener()  
                {  
  
                    @Override  
                    public void onClick(DialogInterface dialog, int which)  
                    {  
                        // 添加手势  
                        sStore.addGesture(name, gesture);  
                        // 保存添加的手势  
                        sStore.save();      
                    }  
                });  
        //绑定对话框的取消按钮监听事件  
        dialogBuider.setNegativeButton("取消", new OnClickListener()  
                {  
  
                    @Override  
                    public void onClick(DialogInterface dialog, int which)  
                    {  
                        // TODO Auto-generated method stub  
                                                       
                    }  
                });  
        //显示对话框  
        dialogBuider.show();  
    }  
      
    private int gestureColor(int resId)  
    {  
        return getResources().getColor(resId);  
    }  
      
    private void showMessage(String s)  
    {  
        Toast.makeText(this, s, Toast.LENGTH_SHORT).show();  
    }  
          
    @Override  
    protected void onDestroy()   
    {  
        // TODO Auto-generated method stub  
        super.onDestroy();  
        //移除绑定的监听器  
        mDrawGestureView.removeOnGesturePerformedListener(this);  
    }  
  
}

main.xml

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical" >  
  
   <android.gesture.GestureOverlayView   
       android:id="@+id/gesture"  
       android:layout_width="fill_parent"  
       android:layout_height="fill_parent"  
       >      
   </android.gesture.GestureOverlayView>  
  
</LinearLayout>

对话框show_gesture.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <LinearLayout 
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="8dip"
            android:text="@string/set_gesture_name"/>
        <EditText 
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
          
    </LinearLayout>

    <ImageView 
        android:id="@+id/show"
        android:layout_gravity="center"
        android:layout_width="128dp"
        android:layout_height="128dp"
        android:layout_marginTop="10dp"/>
</LinearLayout>
相关文章
相关标签/搜索