事件分发

问题:

  1. 自定义View的基础知识
  2. View ViewGroup对Ev处理的方法
  3. Ev传递流向
  4. View.setOntouchListener onTouch 执行顺序与View onTouchEvent() 的优先
  5. 点击事件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的时候 会去判断执行事件。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值