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

一.手势事件的监听方式

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

2.事件类型的判断

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

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

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

4.事件传递的3个阶段


第一阶段是  分发/拦截阶段 ondispatchEvent和onInteceptorEvent(一般在此阶段处理事件,可能导致事件无法传递)

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


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

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

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

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


很显然,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>


转载于:https://my.oschina.net/ososchina/blog/357414

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值