坐标体系
View坐标
左顶点坐标(相对父控件):
left = getLeft()
top = getTop()
右下角坐标(相对父控件):
right = getRight()
bottom = getBottom()
translationX和translationY代表左顶点相对父控件的偏移值
MotionEvent坐标
getX()和getY():当对当前View左上角x和y的坐标
getRawX()和getRawY():相对手机屏幕左上角的x和y的坐标
事件分发
流程
Activity ---> PhoneWindow ---> DecorView ---> ViewGroup -->....> View
伪代码
public boolean dispatchTouchEvent(MotionEvent e) {
boolean cusume = false;
if (onInterceptTouchEvent(e)) {
cusume = onTouchEvent(e);
} else {
cusume = child.dispatchTouchEvent(e);
}
return consume;
}
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
和setOnTouchListener关系:优先级高于onTouchEvent,如果onTouchListener返回true,则不回调onTouchEvent
和setOnClickListener关系:优先级最低
优先级:setOnTouchListener > onTouchEvent > setOnClickLister
滑动冲突处理
外部处理方式:
外部View的onInterceptTouchEvent通过滑动方向处理retrun値
内部处理方式:
内部View的dispatchEvent 中用requestDisallowInterception来请求父类不处理等
判断当前触摸是否再View内
//(x,y)是否在view的区域内
private boolean isTouchPointInView(View view, int x, int y) {
if (view == null) {
return false;
}
int[] location = new int[2];
view.getLocationOnScreen(location);
int left = location[0];
int top = location[1];
int right = left + view.getMeasuredWidth();
int bottom = top + view.getMeasuredHeight();
//view.isClickable() &&
if (y >= top && y <= bottom && x >= left
&& x <= right) {
return true;
}
return false;
}
主要解决事件拦截相关
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int) ev.getRawX();
int y = (int) ev.getRawY();
if (isTouchPointInView(viewGroup, x, y)) {
iosInterceptFlag = true;
return super.dispatchTouchEvent(ev);
}
//do something
}
网友评论