触摸事件分发

触摸事件

在这里插入图片描述

代码

根布局



public class RootLinearLayout extends LinearLayout {
    public RootLinearLayout(Context context) {
        super(context);
    }

    public RootLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("touch", "RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************");
        boolean b = super.dispatchTouchEvent(ev);

        Log.e("touch", "根--->分发事件结束+" + b);
        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("touch", "RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************");
        boolean b = super.onTouchEvent(event);

        Log.e("touch", "根--->处理事件结束+" + b + event.getAction());
        return b;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.e("touch", "RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************");
        boolean b = super.onInterceptTouchEvent(ev);
        Log.e("touch", "根--->拦截事件结束+" + b);

        return b;
    }
}

父布局


public class ParentLinearLayout extends LinearLayout{
    public ParentLinearLayout(Context context) {
        super(context);
    }

    public ParentLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("touch","ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************");
        boolean b = super.dispatchTouchEvent(ev);
        Log.e("touch","父--->分发事件结束+"+ b);
        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("touch","ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************");
        boolean b = super.onTouchEvent(event);
        Log.e("touch","父--->处理事件结束+"+ b+event.getAction());
        return b;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.e("touch","ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************");
        boolean b = super.onInterceptTouchEvent(ev);
        Log.e("touch","父--->拦截事件结束+"+ b);

        return b;
//        return true;
    }
}

子布局



public class ChildTextView extends AppCompatTextView {
    public ChildTextView(Context context) {
        super(context);
    }

    public ChildTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("touch", "ChildTextView--->dispatchTouchEvent--->子--->分发事件***********************");
        boolean b = super.dispatchTouchEvent(ev);
        Log.e("touch", "子--->分发事件+" + b);
        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("touch", "ChildTextView--->onTouchEvent--->子--->处理事件***********************");
        boolean b = super.onTouchEvent(event);
        Log.e("touch", "子--->处理事件+" + b + event.getAction());
        return b;
    }


}

好的log

考虑根+父两层关系

log1 全部返回false
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件***********************
根--->拦截事件+false
            ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件***********************
            ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件***********************
            父--->拦截事件+false
            ParentLinearLayout--->onTouchEvent--->父--->处理事件***********************
            父--->处理事件+false0
            父--->分发事件+false
RootLinearLayout--->onTouchEvent--->根--->处理事件***********************
根--->处理事件+false0
根--->分发事件+false
log2 只是根布局onInterceptTouchEvent返回true
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+true
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+false0
根--->分发事件结束+false

log3 只是根布局dispatchTouchEvent返回true
处理Down事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false0
        父--->分发事件结束+false
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+false0//0表示为Down事件
根--->分发事件结束+true


处理之后的move事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+false2//2表示move事件
根--->分发事件结束+true

处理之后的up事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+false1//1表示up事件
根--->分发事件结束+true
log4 只是根布局onTouchEvent返回true
处理Down事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
        ParentLinearLayout--->onTouchEvent--->父--->处理事件***********************
        父--->处理事件结束+false0
        父--->分发事件结束+false
        RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+true0//关键在这★★★★★,根布局onTouchEvent返回true,就会导致根布局dispatchTouchEvent返回true,从而使得以后的所有事件被根布局处理
根--->分发事件结束+true


处理move事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+true2
根--->分发事件结束+true

处理up事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+true2
根--->分发事件结束+true
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onTouchEvent--->根--->处理事件开始***********************
根--->处理事件结束+true1
根--->分发事件结束+true

分析1

一、对比log1和log2:

  1. 根布局onInterceptTouchEvent返回true,则父布局接收不到任何事件

二、对比log1和log3:

  1. 根布局dispatchTouchEvent返回false,根布局只接受到了Down事件,没有接收到之后的move、up事件
  2. 根布局dispatchTouchEvent返回true,根布局不仅仅接受到了Down事件,而且会接管之后的所有事件,之后的move、up事件都是由根布局处理的,其子布局不会在接收到任何事件
  3. 还可以看到一点,只要根布局在第一次Down事件时dispatchTouchEvent返回true,以后不会再去询问根布局的onInterceptTouchEvent方法,是由根布局自己直接处理触摸事件的
    在这里插入图片描述
  4. 是当前ViewGroup拦截后,就不会再次询问onInterceptTouchEvent方法,但是如果是其子View处理了事件,是会继续询问onInterceptTouchEvent的,下图解释了

在这里插入图片描述


三、对比log1和log4:
1.可以看出,根布局onTouchEvent返回true,就会导致根布局dispatchTouchEvent返回true,从而使得以后的所有事件被根布局处理

即:onTouchEvent(true)---->dispatchTouchEvent(true)---->处理以后的所有事件

log5 只是父布局dispatchTouchEvent返回true
//第一次down事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false0
        父--->分发事件结束+true
根--->分发事件结束+true

//第二次move事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false2
        父--->分发事件结束+true
根--->分发事件结束+true

//第三次move事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false2
        父--->分发事件结束+true
根--->分发事件结束+true


//第四次up事件
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false1
        父--->分发事件结束+true
根--->分发事件结束+true
分析2

对比log1和log5
1.只是父布局dispatchTouchEvent返回true,发现根布局的dispatchTouchEvent也返回了true,说明一个ViewGroup的dispatchTouchEvent返回值,不但与他自身的onTouchEvent返回值有关系,还与他的子View的dispatchTouchEvent有关系
2.子dispatchTouchEvent(true)—>父dispatchTouchEvent(true
3.自身onTouchEvent(true)—>自身onTouchEvent(true)
4.如果下级的dispatchTouchEvent返回了true,以后的事件都有下级处理(当然有多个下级的情况,最下级返回true,他的上级都会返回true,那么以后的事件交给最下级的那个返回true的View处理)

在这里插入图片描述

在这里插入图片描述

考虑根+父+子三层关系

log1 全部返回false
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件***********************
根--->拦截事件+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件***********************
        父--->拦截事件+false
                ChildTextView--->dispatchTouchEvent--->子--->分发事件***********************
                ChildTextView--->onTouchEvent--->子--->处理事件***********************
                子--->处理事件+false0
                子--->分发事件+false
        ParentLinearLayout--->onTouchEvent--->父--->处理事件***********************
        父--->处理事件+false0
        父--->分发事件+false
RootLinearLayout--->onTouchEvent--->根--->处理事件***********************
根--->处理事件+false0
根--->分发事件+false

log2 只是子View的onTouchEvent返回true

//down
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
                ChildTextView--->dispatchTouchEvent--->子--->分发事件开始***********************
                ChildTextView--->onTouchEvent--->子--->处理事件开始***********************
                子--->处理事件结束+true0
                子--->分发事件结束+true
        父--->分发事件结束+true
根--->分发事件结束+true


//move
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
                ChildTextView--->dispatchTouchEvent--->子--->分发事件开始***********************
                ChildTextView--->onTouchEvent--->子--->处理事件开始***********************
                子--->处理事件结束+true2
                子--->分发事件结束+true
        父--->分发事件结束+true
根--->分发事件结束+true


//move
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
                ChildTextView--->dispatchTouchEvent--->子--->分发事件开始***********************
                ChildTextView--->onTouchEvent--->子--->处理事件开始***********************
                子--->处理事件结束+true2
                子--->分发事件结束+true
        父--->分发事件结束+true
根--->分发事件结束+true


//up
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
                ChildTextView--->dispatchTouchEvent--->子--->分发事件开始***********************
                ChildTextView--->onTouchEvent--->子--->处理事件开始***********************
                子--->处理事件结束+true1
                子--->分发事件结束+true
        父--->分发事件结束+true
根--->分发事件结束+true

####分析

  1. 如果子View的onTouchEvent返回true,导致子View的dispatchTouchEvent返回true,那么不会再次调用上层ViewGroup的onTouchEvent,而是直接调用其上层ViewGroup的dispatchTouchEvent,并且返回true
  2. 以后所有事件都交由子View处理
log3 只是父ViewGroup的dispatchTouchEvent返回true
//down
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onInterceptTouchEvent--->父--->拦截事件开始***********************
        父--->拦截事件结束+false
                ChildTextView--->dispatchTouchEvent--->子--->分发事件开始***********************
                ChildTextView--->onTouchEvent--->子--->处理事件开始***********************
                子--->处理事件结束+false0
                子--->分发事件结束+false
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false0
        父--->分发事件结束+true
根--->分发事件结束+true



//move
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
        ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
        ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
        父--->处理事件结束+false2
        父--->分发事件结束+true
根--->分发事件结束+true



//up
RootLinearLayout--->dispatchTouchEvent--->根--->分发事件开始***********************
RootLinearLayout--->onInterceptTouchEvent--->根--->拦截事件开始***********************
根--->拦截事件结束+false
ParentLinearLayout--->dispatchTouchEvent--->父--->分发事件开始***********************
ParentLinearLayout--->onTouchEvent--->父--->处理事件开始***********************
父--->处理事件结束+false1
父--->分发事件结束+true
根--->分发事件结束+true
分析
  1. 只是父ViewGroup的dispatchTouchEvent返回true,这里虽然onInterceptTouchEvent依然返回false,以后的事件都交给了父ViewGroup处理了,而且以后不再询问自身的onInterceptTouchEvent方法了
  2. 可见只要dispatchTouchEvent返回true就表明,以后都是他 来处理事件,
  3. dispatchTouchEvent是一个重要标志,而不是onTouchEvent,只不过默认情况下onTouchEvent返回了true,会导致dispatchTouchEvent返回true,所以看起来onTouchEvent是决定了以后的事件由他处理的标志,但在本例中,onTouchEvent返回false,但我们强行让dispatchTouchEvent返回true。
log4 只是子View的dispatchTouchEvent返回true

log不贴了,直接说结果:
子View接着处理以后的所有事件
所以说最下级的那个dispatchTouchEvent返回ture的view处理以后的事件

总结

public class WeiDaiMa {

    WeiDaiMa child;


    /**
     * ViewGroup的dispatchTouchEvent
     * 用来分发触摸事件
     * 虽然ViewGroup继承自View,但是他重写了dispatchTouchEvent方法,所以这里区分一下
     *
     * @param ev
     * @return
     */

    public boolean dispatchTouchEvent4ViewGroup(MotionEvent ev) {
        Boolean consume = false;

        if (当前ViewGroup要不要拦截事件(ev)) {//如果本ViewGroup拦截事件,那么调用本ViewGroup的onTouchEvent
            consume = onTouchEvent(ev);
        } else {//否则,调用子View的dispatchTouchEvent,子ViewGroup的dispatchTouchEvent逻辑是一样的
            consume = child.dispatchTouchEvent4ViewGroup(ev);如果child为viewgroup
//            consume = child.dispatchTouchEvent4View(ev);//如果child为view
        }

        return consume;//返回true,表示事件被消耗了,
        // 如果是最里层级的view或ViewGroup的dispatchTouchEvent返回true,表示由本ViewGroup来处理以后的事件

    }

    private boolean 当前ViewGroup要不要拦截事件(MotionEvent ev) {
        boolean intercepted;
        if (ev.getAction() == MotionEvent.ACTION_DOWN
                || 本ViewGroup有子View_且_本ViewGroup不拦截事件_交给了子View处理_且_子View的dispatchTouchEvent返回true_即子View处理了事件) {
            if (子View请求拦截_requestDisallowInterceptTouchEvent(false)) {
                //询问本ViewGroup的onInterceptTouchEvent,要不要拦截事件
                intercepted = onInterceptTouchEvent(ev);
            } else {
                intercepted = false;//如果子View请求不拦截,那么默认返回false
            }
        } else {
            //当这个事件不是ACTION_DOWN,并且当前的ViewGroup也没有子ViewGroup(view)可以处理事件,那么就由本ViewGroup拦截这个事件
            intercepted = true;
        }
        return intercepted;
    }

    /**
     * ViewGroup 和 View 的onTouchEvent是一样的 都是view的,
     * 因为ViewGroup是view的子类,且ViewGroup没有重写view的onTouchEvent
     * 用来处理触摸事件
     *
     * @param ev
     * @return
     */
    private Boolean onTouchEvent(MotionEvent ev) {

//            如果控件可点击返回true,否则返回false
        if (isClickable || isLongClickable) {
//            onTouchListener.onTouch--优先于-》onTouchEvent-优先于--》onClick
//            执行click接口
            return true;
        } else {
            return false;
        }
    }

    /**
     * ViewGroup特有的方法
     * 用来判断是否拦截触摸事件
     * 这个方法不一定每次都要都要,他是有条件的 ,见 《当前ViewGroup要不要拦截事件》
     *
     * @param ev
     * @return
     */
    private boolean onInterceptTouchEvent(MotionEvent ev) {

//默认返回false,
// 可以在这里重写,定义在down时候,返回false不拦截
// down up事件返回true拦截   配合子view的requestDisallowIntenceot方法
//        其实requestDisallowInterceptTouchEvent(false)):子view请求拦截,让父view去询问下自己的onInterceptTouchEvent方法,看看要不要拦截
//        如果requestDisallowInterceptTouchEvent(true):子view请求不要拦截,那就直接返回false,不去拦截
        return false;
    }


//    ===================================================================================================

    /**
     * View的dispatchTouchEvent
     * 用来分发触摸事件
     *
     * @param ev
     * @return
     */

    public boolean dispatchTouchEvent4View(MotionEvent ev) {
//        如果控件可用&&设置了mOnTouchListener,&&onTouch方法返回true,该方法直接返回true,不去调用onTouchEvent方法
        if (mOnTouchListener != null && enable && mOnTouchListener.onTouch(ev)) {
            return true;
        } else {
            return onTouchEvent(ev);
        }


    }


}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结

精华1

  1. dispatchTouchEvent:

    所有的事件分发,都是从父ViewGroup的dispatchTouchEvent开始的

      public boolean dispatchTouchEvent(MotionEvent ev) {
            Boolean consume = false;
            if (当前ViewGroup要不要拦截事件(ev)) {
            //如果本ViewGroup拦截事件,那么调用本ViewGroup的onTouchEvent
                consume = onTouchEvent(ev);
            } else {
            //否则,调用子View的dispatchTouchEvent,子ViewGroup的dispatchTouchEvent逻辑是一样的
                consume = child.dispatchTouchEvent(ev);
            return consume;//返回true,表示事件被消耗了,
            // 如果是最里层级的view或ViewGroup的dispatchTouchEvent返回true,表示由本ViewGroup来处理以后的事件
    
        }
    
  2. onInterceptTouchEvent:

    在dispatchTouchEvent内部调用,准确地说是在《当前ViewGroup要不要拦截事件(ev)》这个方法里调用。
    (《…》这是我自己抽取的一个方法,其实也是在dispatchTouchEvent内部调用)

    注意:onInterceptTouchEvent不一定每次都调用,仅仅当down事件来临时,或者其子view已经成功处理了触摸事件时,才会调用,换句话说,如果子view如果没有处理事件,那么,就不会询问onInterceptTouchEvent方法了,直接返回true,自己处理

    《当前ViewGroup要不要拦截事件(ev)》—这个方法的具体逻辑是

    
    
    
     boolean intercepted;
       if(DOWN事件 |或| 其子view消费了触摸事件) {
            if (子View请求拦截) {//即:requestDisallowInterceptTouchEvent(false)
                //询问本ViewGroup的onInterceptTouchEvent,要不要拦截事件
                intercepted = onInterceptTouchEvent(ev);
            } else {
                //如果子View请求不拦截,那么直接返回false
                intercepted = false; 
                    }
        } else {
            //当这个事件不是ACTION_DOWN,并且当前的ViewGroup也没有子ViewGroup(view)可以处理事件,那么就由本ViewGroup拦截这个事件
            intercepted = true;
        }
        return intercepted;
    
  3. 说下requestDisallowInterceptTouchEvent(boolean)

    注意是在子view里通过,getParent().requestDisallowInterceptTouchEvent(boolean)来使用

    - requestDisallowInterceptTouchEvent(false):
    子view请求拦截,让父view去询问下自己的onInterceptTouchEvent方法,看看要不要拦截
    
    - requestDisallowInterceptTouchEvent(true):
    子view请求不要拦截,那就直接返回false,不去拦截
       
    
  4. onTouchEvent

    也是在dispatchTouchEvent内部调用的,但是他是当ViewGroup要处理事件时候,通过调用该ViewGroup的父类View.dispatchTouchEvent时,调用了onTouchEvent,也就是说,严格来讲,onTouchEvent是View.dispatchTouchEvent调用的

       /**
        * ViewGroup 和 View 的onTouchEvent是一样的 都是view的,
        * 因为ViewGroup是view的子类,且ViewGroup没有重写view的onTouchEvent
        * 用来处理触摸事件
        *
        * @param ev
        * @return
        */
       private Boolean onTouchEvent(MotionEvent ev) {
   
             // 如果控件可点击返回true,否则返回false
           if (isClickable || isLongClickable) {
            //            onTouchListener.onTouch--优先于-》onTouchEvent-优先于--》onClick
            //            执行click接口
               return true;
           } else {
               return false;
           }
       }
       
  1. 说一下View的dispatchTouchEvent

    /**
         * View的dispatchTouchEvent
         * 用来分发触摸事件
         *
         * @param ev
         * @return
         */
    
        public boolean dispatchTouchEvent4View(MotionEvent ev) {
    //        如果控件可用&&设置了mOnTouchListener,&&onTouch方法返回true,该方法直接返回true,不去调用onTouchEvent方法
            if (mOnTouchListener != null && enable && mOnTouchListener.onTouch(ev)) {
                return true;
            } else {
                return onTouchEvent(ev);
            }
    
    
        }
    

    可直接看
    Android事件分发机制 详解攻略,您值得拥有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值