博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android多点触摸手势&手势库GestureLibraries
阅读量:6608 次
发布时间:2019-06-24

本文共 7290 字,大约阅读时间需要 24 分钟。

hot3.png

一.手势事件的监听方式

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

  
       
             

对话框show_gesture.xml

        
                
        
                  

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

你可能感兴趣的文章
Linux Shell常用技巧(五)
查看>>
oracle中decode函数
查看>>
linux系统运维企业常见面试题集合(三)
查看>>
Oracle查询表名及模糊查询
查看>>
Spark 实现自己的RDD,让代码更优雅
查看>>
PHP 精确运算
查看>>
Python基础-Python流程控制
查看>>
Windows Server 2012体验之卸载额外域控制器
查看>>
MySQL主从同步配置实现数据库备份
查看>>
单例设计模式
查看>>
监控Squid的开源工具MySAR
查看>>
linux解压 tar命令
查看>>
安装VMtools失败如何解决
查看>>
添加国际化文件
查看>>
iOS APP提交上架最新流程
查看>>
530A - UART
查看>>
华为服务器虚拟化部署
查看>>
1.3 Illustrator工作区的操作讲解
查看>>
MySQL服务器学习笔记!(一) ——数据库相关概念
查看>>
Eclipse 常用的快捷键及其他常用功能小结
查看>>