android View事件体系
参考
huachao1001:彻底理解View事件体系!坐标
- 位置
top、left、right、bottom
- 平移量 android3.0
x = left + translationX;
y = top + translationY; -
MotionEvent事件对象
- 系列事件
ACTION_UP、ACTION_DOWN、ACTION_MOVE
- 坐标
getX(),getY():相对于当前view左上角的x和y坐标
getRawX(),getRawY():相对于手机屏幕左上角的x和y坐标
KeyEvent
Android按键事件处理流程 -- KeyEventVelocityTracker 速度追踪
//获取实例 享元模式
VelocityTracker vt=VelocityTracker.obtain();
vt.addMovement(event);
//设定计算速度的时间间隔
vt.computeCurrentVelocity(1000);
int xv=(int) vt.getXVelocity();
int yv=(int) vt.getYVelocity();
//回收
vt.clear();//一般在MotionEvent.ACTION_UP的时候调用
vt.recycle();//一般在onDetachedFromWindow中调用
GestureDetector手势检测
//监听器
GestureDetector.OnGestureListener listener=new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
//手指按下的瞬间
return false;
}
@Override
public void onShowPress(MotionEvent e) {
//手指触摸屏幕,并且尚未松开或拖动。与onDown的区别是,onShowPress强调没用松开和没有拖动
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
//手指离开屏幕(单击)
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//手指按下并拖动,当前正在拖动
return false;
}
@Override
public void onLongPress(MotionEvent e) {
//手指长按事件
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//手指快速滑动
return false;
}
};
//设置监听器
GestureDetector mGestureDetector = new GestureDetector(this,listener);
//双击 OnDoubleTapListener
//mGestureDetector.setOnDoubleTapListener(onDoubleTapListener);
//防止长按后无法拖动的问题
mGestureDetector.setIsLongpressEnabled(false);
//事件托管
View.OnTouchEvent(){return mGestureDetector.onTouchEvent(event);}
事件分发机制
事件对象产生
- Activity-->PhoneWindow-->DecorView-->(遍历)ViewGroup
- Activity获取事件对象
Android中MotionEvent的来源和ViewRootImpl
系列事件对象下发
- 系列事件:down-->move-->...-->up
- ViewGroup.dispatchTouchEvent()
- ViewGroup.onInterceptTouchEvent
return true; 拦截 不下发
return false; 不拦截 下发 - 拦截 ViewGroup.onTouchEvent()
- 不拦截 View.dispatchTouchEvent()
事件对象处理
- OnTouch() View.setOnTouchListener(new View.OnTouchListener() {});
return false; 转发View.OnTouchEvent()
return true; 消耗 - View.onTouchEvent()
判断单击/双击...事件,显式调用OnClick(),OnLongClick()
retrun super.onTouchEvent(event);
系列事件对象回传
- View.onTouchEvent()
return true; 系列事件被消耗,不回传
return false; -->ViewGroup.onTouchEvent()
细节
- 一个事件序列只能被一个view拦截并消耗
- ViewGroup默认不拦截事件,即onInterceptTouchEvent默认返回false。
- 如果ViewGroup拦截down,那么这个系列事件都只能由它处理,并且onInterceptTouchEvent不会再被调用。
- View的onTouchEvent默认返回false,即不消耗事件。
- View的onTouchEvent
消耗down 接下来的该系列所有的事件都会交给这个View
不消耗down 接下来的事件系列都不会交给这个View - View没有onInterceptTouchEvent方法
- View的onTouchEvent默认都会消耗事件(返回true),除非它是不可点击的(clickable和longClickable都为false)。view的longClickable默认是false的,clickable则不一定,Button默认是true,而TextView默认是false。
- View的enable属性不影响onTouchEvent的默认返回值。哪怕一个view是disable状态,只要它的clickable或者longClickable有一个是true,那么它的onTouchEvent就会返回true。