View的事件分发

一、自定义View的套路
1. 自定义属性
2. onMeasure用于测量控件的大小
3. onDraw用于绘制内容
4. onTouchEvent用于用户交互
二、自定义ViewGroup的套路
1. 自定义属性
2. onMeasure for循环测量子View的宽高,最后计算自己的宽高 
3. onLayout 用于摆放子View,前提是View不是Gone的情况
4. onDraw用于绘制自己,默认是不调用,如果要绘制就复写dispatchDraw
5. onTouchEvent用于用户交互
三、View的事件分发,两个重要方法
1. dispatchTouchEvent(MotionEvent event) 负责事件分发,事件是从这个方法开始分发的。
2. onTouchEvent(MotionEvent event) 触摸事件。
四、dispatchTouchEvent(MotionEvent event)源码分析
public boolean dispatchTouchEvent(MotionEvent event) {
   
    boolean result = false;

    if (onFilterTouchEventForSecurity(event)) {
        // ListenerInfo 封装事件监听的对象,里面封装了一系统列的事件监听回调对象
        // 只要是设置了监听事件,这个对象就不为空。
        ListenerInfo li = mListenerInfo;
        
      // 1. 如果给View设置了OnTouchListener,
      // 那么就会先调用 li.mOnTouchListener.onTouch(this, event)这个方法
      // 如果onTouch返回 false , result就是false
      // 如果onTouch返回 true,    result就是true
        if (li != null && li.mOnTouchListener != null
                && (mViewFlags & ENABLED_MASK) == ENABLED // 控件是enabled
                && li.mOnTouchListener.onTouch(this, event)) {
            result = true;
        }
        // 如果没有设置OnTouchListener,或者onTouch返回false用户没有消费事件
        // 那么就会走View的onTouchEvent方法
        if (!result && onTouchEvent(event)) {
            result = true;
        }
    }
    return result;
}
  1. 如果View没有设置OnTouchListener,或者设置OnTouchListener且onTouch返回false,用户没有消费事件,那么就会走View的 onTouchEvent(event)方法
五、onTouchEvent(MotionEvent event)源码分析
public boolean onTouchEvent(MotionEvent event) {
    final float x = event.getX();
    final float y = event.getY();
    final int viewFlags = mViewFlags;
    final int action = event.getAction();

    if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
        switch (action) {
            // 在onTouchEvent 事件抬起的方法,里面有对点击事件的处理
            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();
                            }
                        }
                    }

                break;
            // 在onTouchEvent 事件抬起的方法,里面有对LongClick点击事件的处理
            case MotionEvent.ACTION_DOWN:
                checkForLongClick(0, x, y);
                break;

        }

        return true;
    }

    return false;
}
// 执行点击事件
public boolean performClick() {
    final boolean result;
    final ListenerInfo li = mListenerInfo;
    if (li != null && li.mOnClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
        // 执行点击事件
        li.mOnClickListener.onClick(this);
        result = true;
    } else {
        result = false;
    }
    return result;
}
  1. 点击和长按事件都在View的onTouchEvent里面
  2. 点击事件的处理是在onTouchEvent ACTION_UP里面
  3. 长按事件的处理是在onTouchEvent ACTION_DOWN里面
  4. OnTouchListener的onTouch方法返回false,事件执行顺序:OnTouchListener-->onTouchEvent-->onClickListener
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Andorid 写 View 的时候总会遇到滑动冲突问题,解决 View 的滑动冲突是十分重要的,因此需要对 An...
    风信子丶阅读 3,474评论 0 4
  • 1.点击事件的传递规则 首先我们先看看下面一段伪代码,通过它我们可以理解到点击事件的传递规则: 上面代码主要涉及到...
    MryU93阅读 4,811评论 0 8
  • 事件分发机制在View体系中几乎是最重要的知识点,理解透彻后在以后自定义各种复杂的View时我们就能更加得心应手了...
    shenhuniurou阅读 3,590评论 0 2
  • 梓奕我儿,现在我们家里到了最困难的时候了。 一场新冠肺炎瘟疫,给我们家造成的影响远远超乎了我的估量。现在开学的日子...
    广土飞升阅读 1,618评论 0 3
  • 人生有时候就是这样,痛快地喝点酒让筋骨舒缓,然后一切就都清晰起来了。——作家,双雪涛 可是对于不喝酒的人来说,怎么...
    007妈咪阅读 1,443评论 0 0