问题:
- 自定义View的基础知识
- View ViewGroup对Ev处理的方法
- Ev传递流向
- View.setOntouchListener onTouch 执行顺序与View onTouchEvent() 的优先
- 点击事件OnClickListener onclick与onTouchEvent()的关系
自定义View基础知识
MotionEvent
ACTION_DOWN 按下
ACTION_UP 抬起
ACTION_MOVE 移动
ACTION_CANCLE 取消.已废弃 归为ACTION_UP
event.getX() view Rect里的坐标
event.getRawX() Window里的坐标
类似 View getScrollX() getScrollY() 只有执行过scrollTo()和scrollBy() 方法才有值
scrollTo() 绝对位移
scrollBy() 相对位移 调用多次 位置会一直改变
Scroll 滑动辅助类 有点类似差值器 最终还是实现scrollTo/scrollBy实现滑动
下面简单示例:
public void zoomIn() {
// Revert any animation currently in progress
mScroller.forceFinished(true);
// Start scrolling by providing a starting point and
// the distance to travel x 正数向左 y正数向上 和坐标系相反
mScroller.startScroll(0, 0, 100, 0);
// Invalidate to request a redraw
invalidate();
}
if (mScroller.computeScrollOffset()) {
// Get current x and y positions
int currX = mScroller.getCurrX();
int currY = mScroller.getCurrY();
...
}
位置坐标系 左上角为原点 X正向向左 Y正向向下
View ViewGroup对Ev处理的方法
ViewGroup
onDispatchTouchEvent() 一般不重写 里面有复杂的判断逻辑
onIntercepterEvent() ViewGroup特有的 用于拦截事件向下传递 默认返回false 若返回true 执行当前View onTouchEvent()
onTouchEvent() rentrun true 代表消费 接受ACTION_DOWN为起点 后续的事件都会传递给当前View
View
onDispatchTouchEvent()
onTouchEvent()
ViewGroup
onDispatchTouchEvent() 一般不重写 里面有复杂的判断逻辑
onIntercepterEvent() ViewGroup特有的 用于拦截事件向下传递 默认返回false 若返回true 执行当前View onTouchEvent()
onTouchEvent() rentrun true 代表消费 接受ACTION_DOWN为起点 后续的事件都会传递给当前View
View
onDispatchTouchEvent()
onTouchEvent()
Ev传递流向
Activiy->ViewGroup->View 如未处理 View->ViewGroup->Activity
真正事件接受的起点其实是ViewRootImpl WindowInputEventReceiver 具体可以参考用户获取到触摸事件回调最开始的地方
View.setOntouchListener onTouch 执行顺序与View onTouchEvent() 的优先
dispatchTouchEvent(){
.....
if (onFilterTouchEventForSecurity(event)) {
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
result = true;
}
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
.....
}
onTouch()的判断在onTouchEvent()之前 如果返回true 就不走onTouchEvent()的判断
点击事件OnClickListener onclick与onTouchEvent()的关系
onTouchEvent(){
.....
if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
switch (action) {
case MotionEvent.ACTION_UP:
...........
if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
// Only perform take click actions if we were in the pressed state
if (!focusTaken) {
// Use a Runnable and post this rather than calling
// performClick directly. This lets other visual state
// of the view update before click actions start.
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
}
}
......
}
}
当ACTION_UP的时候 会去判断执行事件。