Touch事件和手势处理
- Touch事件
·Touch事件:用户的手势操作
·Android设备中的应用程序主要依赖于用户的各种手势操作实现交互,常见的手势操作有:单击、长按,滑动。
onTouchEvent()方法
·在view类中定义了onTouchEvent()方法,用于处理Touch事件,View的每个子类都可以重写该方法,以决定该view如何处理Touch事件,方法签名为:
- public boolean onTouchEvent(MotionEvent event)
·在Activity类中也定义了onTouchEvent()方法,则每个Activity的子孙类都可以重写该方法,用于决定当前Activity中如何处理Touch事件,该方法签名与View类定义的onTouchEvent()方法的签名完全相同。
View.OnTouchListener接口
·在View类中定义了setOnTouchListener()方法,用于为View对象指定Touch事件处理监听器,该方法的参数类型是View.OnTouchListener接口,接口中的抽象方法签名为:
- boolean onTouch(View v ,MotionEvent event);
MotionEvent类
无论View类或Activity类中定义的onTouchEvent()方法,或View类中的OnTouchListener接口的抽象方法中,都使用了MotionEvent的对象作为参数,该类的常用方法有:
·public final int getAction() //用于获取Touch事件是属于哪类型的事件(如:按下或者离开)
·public final float getX() //当前正在操作的手触碰到频幕后,对应到点的X轴的坐标
·public final float getX(int pointerIndex) //多点触碰
·public final float getY() //当前正在操作的手触碰到频幕后,对应到点的Y轴的坐标
·public final float getY(int pointerIndex)
·MotionEvent类中定义了一系列的常量,用于标识Touch操作的类型,亦可用于尝试匹配getAction()方法的返回值,常用的常量有:
·public static final int ACTION_DOWN //当手刚好按到屏幕的那一刻
·public static final int ACTION_UP //手刚好从屏幕上离开的那一刻
·public static final int ACTION_MOVE //手按下屏幕正在移动时处理Touch事件方法的返回值
·无论View类或Activity类中定义的onTouchEvent()方法,或View类中的OnTouchListener接口的抽象方法,各方法的返回值均是boolean类型。
·由于同一次的某个操作可能导致多个处理Touch事件的方法被回调,当方法的返回值被指定为true时,表示当前方法已“消费”该事件,则后续尝试处理该Touch事件的方法不会被回调,如果返回值被指定为false时,则后续尝试处理该Touch事件的方法会正常执行。处理Touch事件:
·View.onTouchEvent()
·Activity.onTouchEvent()
·View.setOnTouchListener()简单的自定义View
·当需要自定义View时,需要创建新的Java类,继承自View或者View的子孙类。
·由于View没有无参数的构造方法,则自定义View需要显示的创建带参数的构造方法:
·如果希望在程序中使用new关键字创建自定义view的对象,则必须显示的创建带1个参数的构造方法;
·如果希望在res\layout\下的布局文件中使用自定义View设计布局,则必须显示的创建带2个参数或者带3个参数的构造方法。Touch事件的派发和处理逻辑
·在Android系统中,视图系统大致分为View与ViewGroup:
- View是一般独立显示了具体内容的控件,例如:TextView,ImageView等;
- ViewGroup是用于承载其他控件的,例如RelativeLayout、ListView等。
·当出现Touch事件时,需要明确是由View或是ViewGroup处理事件。·在Android系统中,视图系统中存在3个方法处理Touch事件相关逻辑:
- public boolean dispatchTouchEvent(MotionEvent ev):处理事件分发;
- public boolean onInterceptTouchEvent(MotionEvent ev): 处理事件拦截;
- public boolean onTouchEvent(MotionEvent ev): 处理事件响应。
·由于简单的View对象不存在子级控件,所以并不存在事件拦截的操作,即没有OnInterceptEvent()方法。·每个ViewGroup在接收到事件后,默认遵循“分发 –> 拦截 –> 处理”的流程执行相关的方法。
·在默认情况下:
- 事件分发:“隧道式”,即从最外层控件依次传递,直至最内层子级控件,也就是说,越靠近根节点,分发的权力越大。
- 事件处理:“冒泡式”,即从最内层子级控件开始处理,直到最外层的控件。事件分发(dispatchTouchEvent)的逻辑如下:
- 当返回值true时,由dispatchTouchEvent()直接消费,事件将不再传递,即不会拦截,相应,更不会向分发到其它控件;
- 当返回值为false时:
·如果事件是Activity获取的,则由Activity的onTouchEvent()消费;
·如果事件是父控件的,则由父控件的onTouchEvent()消费。事件拦截(onInterceptTouchEvent)的逻辑如下:
- 当返回值为true时,表示当前控件拦截事件,且当前控