簡單明了的分析Android觸摸事件,看完再也不糾結(jié)了

關(guān)于Android觸摸事件機制

Android觸摸事件機制,開發(fā)中都是老生常談,但是慚愧的是,這么久開發(fā),依然對Android觸摸事件的具體流程,懵懵懂懂,趁著項目上線間隙,來重新研究一下。

準備

為了盡可能簡單并清晰的展示Android觸摸事件的 分發(fā)--攔截--消費過程,將根據(jù)Activity、ViewGroup以及View的特點,做了一點準備工作。

觸摸事件:

  • actionDown
  • actionMove
  • actionUp

對于Android事件處理分為兩類

對于Activity和View: 只有兩種事件:

  • 分發(fā): dispatchTouchEvent函數(shù)
  • 消費: onTouchEvent函數(shù)和OnTouchListener函數(shù)

對于ViewGroup: 全部三種事件:

  • 分發(fā): dispatchTouchEvent函數(shù)
  • 攔截:onInterceptTouchEvent函數(shù)
  • 消費: onTouchEvent函數(shù)和OnTouchListener函數(shù)

所以,重寫一個典型的ViewGroup:RelativeLayout和一個典型的View:TextView,針對他們的觸摸事件進行改寫,來得出觸摸事件具體的流程。

TouchRelativeLayout

public class TouchRelativeLayout extends RelativeLayout {
    public TouchRelativeLayout(Context context) {
        super(context);
    }

    public TouchRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TouchRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        LogUtils.e("ViewGroup-------dispatchTouchEvent-------", ev.getAction() + "");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        LogUtils.e("ViewGroup-------onInterceptTouchEvent-------", ev.getAction() + "");
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LogUtils.e("ViewGroup-------onTouchEvent-------", event.getAction() + "");
        return super.onTouchEvent(event);
    }
}

TouchTextView

public class TouchTextView extends TextView {
    public TouchTextView(Context context) {
        super(context);
    }

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

    public TouchTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        LogUtils.e("View---------dispatchTouchEvent-------", ev.getAction() + "");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LogUtils.e("View---------onTouchEvent-------", event.getAction() + "");
        return super.dispatchTouchEvent(event);
    }
}

代碼里不進行任何操作,只打印出當前控件的觸摸事件。
繼續(xù)新建一個Activity,為觸摸事件提供入口:

Activity的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <com.ddz.lifestyle.baseview.customview.TouchRelativeLayout
        android:id="@+id/rl_touch"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:background="@android:color/holo_blue_light">

        <com.ddz.lifestyle.baseview.customview.TouchTextView
            android:id="@+id/tv_touch"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_centerInParent="true"
            android:background="@color/recy_bg" />
    </com.ddz.lifestyle.baseview.customview.TouchRelativeLayout>
</RelativeLayout>

忽略外層的RelativeLayout,實際就是一個Activity中,一個ViewGroup包裹一個View,Activity中不進行操作,只打印出觸摸事件:

   @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        LogUtils.e("activity-------dispatchTouchEvent-------", ev.getAction() + "");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LogUtils.e("activity-------onTouchEvent-------", event.getAction() + "");
        return super.onTouchEvent(event);
    }
    

運行程序,打開要觸摸的Activity,顯示效果,藍色區(qū)域為重寫的TouchRelativeLayout,其中的灰色區(qū)域就是重寫的TouchTextView

image

開始分析:

1、默認不改寫任何事件

  • 1、觸摸A區(qū)域(按下、抬起)
08-10 14:58:08.131 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 14:58:08.132 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 14:58:08.697 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 14:58:08.697 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

根據(jù)日志分析:記錄下了Activity的分發(fā)dispatchTouchEvent和onTouchEvent事件,0為按下動作,1為抬起動作。

得出結(jié)論:默認Activity將觸摸事件分發(fā)下去,并且沒有子View消費情況下, 自己消費;

  • 2、觸摸B區(qū)域(按下、移動、抬起)
08-10 15:11:43.128 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 15:11:43.129 11780-11780/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 15:11:43.129 11780-11780/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 15:11:43.129 11780-11780/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 15:11:43.129 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 15:11:43.519 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:11:43.519 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:11:43.536 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:11:43.536 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:11:43.553 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:11:43.553 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:11:43.569 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:11:43.570 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:11:43.875 11780-11780/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 15:11:43.875 11780-11780/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:

1、按下后,Activity將事件分發(fā)給ViewGroup,ViewGroup返回默認super.dispatchTouchEvent(ev)將事件分發(fā)下去并傳遞給ViewGroup的onInterceptTouchEvent函數(shù);

2、onInterceptTouchEvent返回默認的super.onInterceptTouchEvent(ev),事件傳遞給ViewGroup的onTouchEvent方法

3、onTouchEvent依然返回默認的super.onTouchEvent(event),不進行消費,將事件返回給上一層的Activity,Activity調(diào)用onTouchEvent,處理了按下事件。

4、手指移動,Activity的dispatchTouchEvent方法將事件分發(fā)。因為按下事件中,已經(jīng)得知Activity中的ViewGroup不對觸摸事件進行任何操作,并將事件返回給Activity,所以聰明的Activity這時候?qū)⒎职l(fā)后的事件自己消費了

5、Activity的onTouchEvent對移動事件自行處理

6、手指抬起:同樣,Activity的dispatchTouchEvent方法將事件分發(fā),自己的onTouchEvent進行消費

  • 3、觸摸C區(qū)域(按下、移動、抬起)
08-10 15:50:20.933 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 15:50:20.933 20620-20620/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 15:50:20.934 20620-20620/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 15:50:20.934 20620-20620/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 15:50:20.934 20620-20620/com.ddz.lifestyle E/View---------onTouchEvent-------: 0
08-10 15:50:20.943 20620-20620/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 15:50:20.944 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 15:50:21.441 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:50:21.441 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:50:21.458 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:50:21.458 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:50:21.475 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:50:21.475 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:50:21.492 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:50:21.492 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:50:21.786 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 15:50:21.786 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 15:50:21.787 20620-20620/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 15:50:21.787 20620-20620/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:結(jié)果和在B區(qū)域觸摸結(jié)果類似

1、按下時,Activity使用dispatchTouchEvent方法將事件分發(fā)給ViewGroup

2、ViewGroup使用dispatchTouchEvent方法默認將事件分發(fā)給自己的onInterceptTouchEvent方法,onInterceptTouchEvent方法默認不攔截,將事件傳遞給其中的View

3、View的dispatchTouchEvent方法默認將事件分發(fā)給自己的onTouchEvent方法,onTouchEvent返回默認super.onTouchEvent(event),將事件回傳給ViewGroup的onTouchEvent方法

4、ViewGroup的onTouchEvent也默認將事件傳遞給Activity的onTouchEvent方法

5、按下事件只好由Activity的onTouchEvent方法自己處理

6、手指移動,Activity已經(jīng)知道其中的ViewGroup及View都不處理觸摸事件,所以使用自己的dispatchTouchEvent方法將移動事件傳遞給自己的onTouchEvent方法消費

7、手指抬起,同第6步一樣,自己分發(fā)自己處理。

2、改寫ViewGroup的dispatchTouchEvent方法,返回false

  • 1、觸摸B區(qū)域(按下、移動、抬起)
08-10 16:22:05.686 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 16:22:05.686 3933-3933/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 16:22:05.686 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 16:22:07.268 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:22:07.268 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:22:07.352 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:22:07.352 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:22:07.436 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:22:07.436 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:22:07.486 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:22:07.486 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:22:07.873 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:22:07.873 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:22:07.890 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:22:07.890 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:22:07.892 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 16:22:07.892 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:

1、按下時,Activity使用dispatchTouchEvent將事件分發(fā)給ViewGroup

2、因為ViewGroup的dispatchTouchEvent返回false,即事件不再繼續(xù)向下分發(fā),事件被返回給Activity的onTouchEvent進行消費

3、手指移動:Activity既然使用dispatchTouchEvent將事件分發(fā),但從按下事件的反饋中,Activity已經(jīng)得知ViewGroup不再分發(fā)事件,并且將事件返回,所以Activity還是自己用onTouchEvent將事件消費了

4、手指抬起:同手指移動一樣,自己分發(fā)自己消費

  • 2、觸摸C區(qū)域(按下、移動、抬起)
08-10 16:31:17.409 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 16:31:17.409 3933-3933/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 16:31:17.409 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 16:31:17.912 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:31:17.912 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:31:17.929 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:31:17.929 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:31:17.963 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:31:17.963 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 16:31:18.194 3933-3933/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 16:31:18.194 3933-3933/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:

1、同觸摸B區(qū)域一的結(jié)果,說明ViewGroupd的ispatchTouchEvent返回false,即不再分發(fā)事件,其中任何View得不到觸摸事件

3、改寫ViewGroup的dispatchTouchEvent方法,返回true

  • 1、觸摸B區(qū)域(按下、移動、抬起)
08-10 16:43:37.080 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 16:43:37.080 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 16:43:37.226 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.226 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.243 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.243 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.260 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.411 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.444 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.445 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.464 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 16:43:37.464 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 1

分析:
1、按下時,Activity使用dispatchTouchEvent方法將事件分發(fā);
2、ViewGroup接收到事件,但是ViewGroup的dispatchTouchEvent返回true,即ViewGroup的dispatchTouchEvent將事件消費,不再分發(fā)。
3、手指移動、手指抬起:同按下狀態(tài)一下,Activity使用dispatchTouchEvent分發(fā)的事件被ViewGroup的dispatchTouchEvent方法消費了。

  • 2、觸摸C區(qū)域(按下、移動、抬起)
08-10 16:43:37.080 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 16:43:37.080 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 16:43:37.226 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.226 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.243 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.243 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.260 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.411 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.444 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 16:43:37.445 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 16:43:37.464 3206-3206/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 16:43:37.464 3206-3206/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 1

分析:View接收不到任何事件,因為ViewGroup的dispatchTouchEvent方法返回true,事件被ViewGroup的dispatchTouchEvent方法消費掉,不再向下傳遞了

4、改寫ViewGroup的onInterceptTouchEvent方法,返回true

  • 1、觸摸B區(qū)域(按下、移動、抬起)
08-10 17:01:03.576 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:01:03.576 16009-16009/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:01:03.576 16009-16009/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:01:03.576 16009-16009/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:01:03.576 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 17:01:04.148 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:01:04.148 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:01:04.165 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:01:04.165 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:01:04.448 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:01:04.448 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:01:04.448 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:01:04.448 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:Activity的dispatchTouchEvent將事件分發(fā)給ViewGroup
2、ViewGroup默認的dispatchTouchEvent方法將事件分發(fā),傳遞給onInterceptTouchEvent方法,onInterceptTouchEvent方法返回true,將事件攔截,供給自己的onTouchEvent方法消費,
3、ViewGroup的onTouchEvent方法默認不消費,將事件返回給Activity的onTouchEvent方法,最終按下事件由Activity的onTouchEvent自己消費
4、手指移動:Activity辛辛苦苦分發(fā)的按下事件,ViewGroup不領(lǐng)情,那么這次移動事件,Activity使用dispatchTouchEvent將事件分發(fā)給自己的onTouchEvent,自己消費掉
5、手指抬起:同手指移動一樣,Activity自己分發(fā)自己消費

  • 2、觸摸C區(qū)域(按下、移動、抬起)
08-10 17:06:27.835 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:06:27.835 16009-16009/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:06:27.835 16009-16009/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:06:27.835 16009-16009/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:06:27.835 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 17:06:27.998 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:06:27.999 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:06:28.015 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:06:28.015 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:06:28.300 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:06:28.300 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:06:28.357 16009-16009/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:06:28.357 16009-16009/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:可以看出,和B區(qū)域事件一樣,ViewGroup的onInterceptTouchEvent將事件攔截后自己又不消費,返回給Activity,并且ViewGroup中的View接受不到事件消息,因為ViewGroup已經(jīng)攔截了事件。

5、改寫ViewGroup的onInterceptTouchEvent方法,返回false

  • 1、觸摸B區(qū)域(按下、移動、抬起)
08-10 17:13:47.725 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:13:47.725 19111-19111/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:13:47.725 19111-19111/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:13:47.725 19111-19111/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:13:47.725 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 17:13:47.786 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:13:47.786 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:13:47.803 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:13:47.803 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:13:48.005 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:13:48.005 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:13:48.009 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:13:48.009 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:Activity的dispatchTouchEvent將事件分發(fā)給ViewGroup
2、ViewGroup默認的dispatchTouchEvent方法將事件分發(fā),傳遞給onInterceptTouchEvent方法,onInterceptTouchEvent方法返回false,不再攔截,但是ViewGroup觸摸區(qū)域沒有View,所以事件傳遞給自己onTouchEvent方法
3、ViewGroup的onTouchEvent方法默認不消費,將事件返回給Activity的onTouchEvent方法,最終按下事件由Activity的onTouchEvent自己消費
4、手指移動:Activity辛辛苦苦分發(fā)的按下事件,ViewGroup不領(lǐng)情,那么這次移動事件,Activity使用dispatchTouchEvent將事件分發(fā)給自己的onTouchEvent,自己消費掉
5、手指抬起:同手指移動一樣,Activity自己分發(fā)自己消費

  • 2、觸摸C區(qū)域(按下、移動、抬起)
08-10 17:20:04.767 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:20:04.767 19111-19111/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:20:04.767 19111-19111/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:20:04.767 19111-19111/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 17:20:04.767 19111-19111/com.ddz.lifestyle E/View---------onTouchEvent-------: 0
08-10 17:20:04.768 19111-19111/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:20:04.768 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 17:20:04.896 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:20:04.896 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:20:05.047 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:20:05.047 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:20:05.064 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:20:05.064 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:20:05.081 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:20:05.081 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:20:05.095 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:20:05.095 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:20:05.095 19111-19111/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:20:05.095 19111-19111/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:這次流程依然是Activity的dispatchTouchEvent分發(fā)事件給ViewGroup
2、VIewGroup的dispatchTouchEvent方法返回默認的super.dispatchTouchEvent(ev),所以事件繼續(xù)分發(fā),傳遞給onInterceptTouchEvent;
3、這時候onInterceptTouchEvent已經(jīng)返回false,不再攔截,事件終于被傳遞給ViewGroup中的View了;
4、View接受到事件之后,dispatchTouchEvent方法也是返回默認super.dispatchTouchEvent(ev),事件傳遞給自己的onTouchEvent方法
5、View的onTouchEvent方法不去消費,事件又被返回給ViewGroup的onTouchEvent方法;
6、但是ViewGroup的onTouchEvent方法也不消費,返回給Activity的onTouchEvent方法
7、Activity的onTouchEvent方法自己消費按下事件(Activity:都不消費,下次不給你傳了);
8、Activity說到做到,手指移動和手指抬起事件:Activity使用dispatchTouchEvent方法將事件分發(fā)給自己的onTouchEvent方法消費,自己發(fā)給自己消費,(再也不給下面的ViewGroup和View這兩個什么都不干的人,哈哈哈)

6、改寫ViewGroup的onTouchEvent方法,返回true

  • 1、觸摸B區(qū)域(按下、移動、抬起)
08-10 17:32:42.158 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:32:42.158 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:32:42.158 12826-12826/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:32:42.158 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:32:42.194 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:32:42.194 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 17:32:42.194 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 2
08-10 17:32:42.227 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:32:42.227 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 17:32:42.227 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 2
08-10 17:32:42.428 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:32:42.428 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 17:32:42.428 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 2
08-10 17:32:42.442 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:32:42.442 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 1
08-10 17:32:42.442 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 1

分析:1、手指按下:Activity的dispatchTouchEvent將事件分發(fā)給ViewGroup
2、ViewGroup默認的dispatchTouchEvent方法將事件分發(fā),傳遞給onInterceptTouchEvent方法
3、ViewGroup的onInterceptTouchEvent方法默認返回super.onInterceptTouchEvent(ev),不攔截,但是ViewGroup觸摸區(qū)域沒有View,所以事件傳遞給自己onTouchEvent方法
3、ViewGroup的onTouchEvent方法返回true, 將按下事件消費掉了,不再返回
4、手指移動:Activity的dispatchTouchEvent方法依然分發(fā)事件給ViewGroup;
5、ViewGroup在手指按下事件中已經(jīng)知道了自己的onInterceptTouchEvent方法默認不攔截,所以移動事件就不再問onInterceptTouchEvent方法了,直接傳遞給onTouchEvent方法
6、ViewGroup的onTouchEvent方法將事件消費
7、手指提起:同手指移動一模一樣的流程,最終事件由ViewGroup的onTouchEvent方法消費掉

  • 2、觸摸C區(qū)域(按下、移動、抬起)
08-10 17:39:21.134 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:39:21.135 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:39:21.135 12826-12826/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:39:21.135 12826-12826/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 17:39:21.135 12826-12826/com.ddz.lifestyle E/View---------onTouchEvent-------: 0
08-10 17:39:21.140 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:39:21.261 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:39:21.261 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 17:39:21.261 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 2
08-10 17:39:21.277 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:39:21.278 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 17:39:21.278 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 2
08-10 17:39:21.428 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:39:21.428 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 17:39:21.428 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 2
08-10 17:39:21.435 12826-12826/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:39:21.435 12826-12826/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 1
08-10 17:39:21.435 12826-12826/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 1

分析:
1、手指按下:Activity的dispatchTouchEvent將事件分發(fā)給ViewGroup
2、ViewGroup默認的dispatchTouchEvent方法將事件分發(fā),傳遞給onInterceptTouchEvent方法
3、ViewGroup的onInterceptTouchEvent方法默認返回super.onInterceptTouchEvent(ev),不攔截,這時候ViewGroup中有了View,事件傳遞給View的dispatchTouchEvent
4、View的dispatchTouchEvent將事件分發(fā)給自己的onTouchEvent方法
5、View的onTouchEvent不想消費事件,將事件返回給ViewGroup的onTouchEvent方法
6、ViewGroup的onTouchEvent方法返回true,將事件拿來自己消費掉了,按下事件結(jié)束了
7、手指移動:Activity的dispatchTouchEvent方法依然分發(fā)事件給ViewGroup;
8、ViewGroup在手指按下事件中已經(jīng)知道了自己的onInterceptTouchEvent方法默認不攔截,所以移動事件就不再問onInterceptTouchEvent方法了,而且按下事件的時候,ViewGroup中的View不消費事件,所以這次也不再傳遞給View了,直接傳遞給ViewGroup的onTouchEvent
9、ViewGroup的onTouchEvent方法返回true,所以消費了移動事件
10、手指抬起同手指移動一樣

7、改寫ViewGroup的onTouchEvent方法,返回false

  • 1、觸摸B區(qū)域(按下、移動、抬起)
08-10 17:49:17.141 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:49:17.142 29978-29978/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:49:17.142 29978-29978/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:49:17.142 29978-29978/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:49:17.142 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 17:49:17.245 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:49:17.245 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:49:17.295 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:49:17.295 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:49:17.409 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:49:17.409 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:49:17.409 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:49:17.409 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:Activity的dispatchTouchEvent將事件分發(fā)給ViewGroup
2、ViewGroup默認的dispatchTouchEvent方法將事件分發(fā),傳遞給onInterceptTouchEvent方法;
3、ViewGroup的onInterceptTouchEvent方法返回默認的super.onInterceptTouchEvent(ev),即不攔截,但是ViewGroup觸摸區(qū)域沒有View,所以事件傳遞給自己onTouchEvent方法
3、ViewGroup的onTouchEvent方法返回false,不消費事件,將事件返回給Activity的onTouchEvent方法,最終按下事件由Activity的onTouchEvent自己消費
4、手指移動:Activity辛辛苦苦分發(fā)的按下事件,ViewGroup不領(lǐng)情,那么這次移動事件,Activity使用dispatchTouchEvent將事件分發(fā)給自己的onTouchEvent,自己消費掉
5、手指抬起:同手指移動一樣,Activity自己分發(fā)自己消費

  • 2、觸摸C區(qū)域(按下、移動、抬起)
08-10 17:52:32.229 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 17:52:32.230 29978-29978/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 17:52:32.230 29978-29978/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 17:52:32.230 29978-29978/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 17:52:32.230 29978-29978/com.ddz.lifestyle E/View---------onTouchEvent-------: 0
08-10 17:52:32.230 29978-29978/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 17:52:32.230 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 17:52:32.331 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:52:32.331 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:52:32.348 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:52:32.348 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:52:32.735 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 17:52:32.735 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 17:52:32.740 29978-29978/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 17:52:32.741 29978-29978/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:這次流程依然是Activity的dispatchTouchEvent分發(fā)事件給ViewGroup
2、VIewGroup的dispatchTouchEvent方法返回默認的super.dispatchTouchEvent(ev),所以事件繼續(xù)分發(fā),傳遞給onInterceptTouchEvent;
3、這時候onInterceptTouchEvent也默認不攔截,事件終于被傳遞給ViewGroup中的View了;
4、View接受到事件之后,dispatchTouchEvent方法也是返回默認super.dispatchTouchEvent(ev),事件傳遞給自己的onTouchEvent方法
5、View的onTouchEvent方法默認不消費,事件又被返回給ViewGroup的onTouchEvent方法;
6、但是ViewGroup的onTouchEvent方法返回false,不消費,事件又返回給Activity的onTouchEvent方法
7、Activity的onTouchEvent方法自己消費按下事件(Activity:都不消費,下次不給你傳了);
8、Activity說到做到,手指移動和手指抬起事件:Activity使用dispatchTouchEvent方法將事件分發(fā)給自己的onTouchEvent方法消費,自己發(fā)給自己消費,(再也不給下面的ViewGroup和View這兩個什么都不干的人,哈哈哈)

8、改寫View的dispatchTouchEvent方法,返回false

  • 1、觸摸C區(qū)域(按下、移動、抬起)
08-10 19:20:06.394 29197-29197/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 19:20:06.394 29197-29197/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 19:20:06.394 29197-29197/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 19:20:06.394 29197-29197/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 19:20:06.394 29197-29197/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 19:20:06.395 29197-29197/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 19:20:06.529 29197-29197/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 19:20:06.529 29197-29197/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 19:20:06.563 29197-29197/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 19:20:06.563 29197-29197/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 19:20:06.579 29197-29197/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 19:20:06.580 29197-29197/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 19:20:06.634 29197-29197/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 19:20:06.634 29197-29197/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:Activity的dispatchTouchEvent分發(fā)事件給ViewGroup;
2、VIewGroup的dispatchTouchEvent方法返回默認的super.dispatchTouchEvent(ev),所以事件繼續(xù)分發(fā),傳遞給onInterceptTouchEvent;
3、ViewGroup的onInterceptTouchEvent也默認不攔截,事件終于被傳遞給ViewGroup中的View了;
4、View接受到事件之后,dispatchTouchEvent方法返回false,事件不再分發(fā),返回給ViewGroup的onTouchEvent;
5、ViewGroup的onTouchEvent方法默認也不消費,事件再次返回給Activity的onTouchEvent
6、最終,按下事件由Activity的onTouchEvent方法消費掉。
7、由按下事件可知:事件從View-->ViewGroup-->View,事件最終返回給Activity,所以手指移動、抬起事件,不會再繼續(xù)向下分發(fā),直接有Activity的dispatchTouchEvent傳遞給自己的onTouchEvent事件消費

9、改寫View的dispatchTouchEvent方法,返回true

  • 1、觸摸C區(qū)域(按下、移動、抬起)
08-10 19:29:34.275 22834-22834/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 19:29:34.275 22834-22834/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 19:29:34.275 22834-22834/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 19:29:34.275 22834-22834/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 19:29:34.621 22834-22834/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 19:29:34.621 22834-22834/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 19:29:34.621 22834-22834/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 2
08-10 19:29:34.621 22834-22834/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 2
08-10 19:29:34.637 22834-22834/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 19:29:34.637 22834-22834/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-10 19:29:34.637 22834-22834/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 2
08-10 19:29:34.638 22834-22834/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 2
08-10 19:29:34.642 22834-22834/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 19:29:34.642 22834-22834/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 1
08-10 19:29:34.642 22834-22834/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 1
08-10 19:29:34.642 22834-22834/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 1

分析:
1、手指按下:Activity的dispatchTouchEvent分發(fā)事件給ViewGroup;
2、VIewGroup的dispatchTouchEvent方法返回默認的super.dispatchTouchEvent(ev),所以事件繼續(xù)分發(fā),傳遞給onInterceptTouchEvent;
3、ViewGroup的onInterceptTouchEvent默認不攔截,事件終于被傳遞給ViewGroup中的View了;
4、View接受到事件之后,dispatchTouchEvent方法返回true,事件不再分發(fā),直接被View的dispatchTouchEvent消費,不再傳遞
5、手指移動、手指抬起事件同上,全部被View的dispatchTouchEvent方法消費

10、改寫View的onTouchEvent方法,返回false

  • 1、觸摸C區(qū)域(按下、移動、抬起)
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/View---------onTouchEvent-------: 0
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/ViewGroup-------onTouchEvent-------: 0
08-10 21:18:33.082 8039-8039/com.ddz.lifestyle E/activity-------onTouchEvent-------: 0
08-10 21:18:33.108 8039-8039/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 21:18:33.108 8039-8039/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 21:18:33.125 8039-8039/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 21:18:33.125 8039-8039/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 21:18:33.141 8039-8039/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-10 21:18:33.141 8039-8039/com.ddz.lifestyle E/activity-------onTouchEvent-------: 2
08-10 21:18:33.248 8039-8039/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-10 21:18:33.248 8039-8039/com.ddz.lifestyle E/activity-------onTouchEvent-------: 1

分析:
1、手指按下:這次流程依然是Activity的dispatchTouchEvent分發(fā)事件給ViewGroup
2、VIewGroup的dispatchTouchEvent方法返回默認的super.dispatchTouchEvent(ev),所以事件繼續(xù)分發(fā),傳遞給onInterceptTouchEvent;
3、這時候onInterceptTouchEvent也默認不攔截,事件終于被傳遞給ViewGroup中的View了;
4、View接受到事件之后,dispatchTouchEvent方法也是返回默認super.dispatchTouchEvent(ev),事件傳遞給自己的onTouchEvent方法
5、View的onTouchEvent方法返回false,不消費事件,事件又被返回給ViewGroup的onTouchEvent方法;
6、但是ViewGroup的onTouchEvent方法默認不消費,事件又返回給Activity的onTouchEvent方法
7、最后Activity的onTouchEvent方法自己消費按下事件(Activity:都不消費,下次不給你傳了);
8、手指移動:Activity已經(jīng)知道ViewGroup和View都不消費事件,所以手指移動事件就自己使用dispatchTouchEvent傳遞給自己的onTouchEvent方法消費掉
9、手指抬起:同手指移動

11、改寫View的onTouchEvent方法,返回true

  • 1、觸摸C區(qū)域(按下、移動、抬起)
08-11 13:33:27.684 11900-11900/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 0
08-11 13:33:27.684 11900-11900/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 0
08-11 13:33:27.684 11900-11900/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 0
08-11 13:33:27.684 11900-11900/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 0
08-11 13:33:27.685 11900-11900/com.ddz.lifestyle E/View---------onTouchEvent-------: 0
08-11 13:33:27.761 11900-11900/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-11 13:33:27.761 11900-11900/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-11 13:33:27.761 11900-11900/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 2
08-11 13:33:27.761 11900-11900/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 2
08-11 13:33:27.761 11900-11900/com.ddz.lifestyle E/View---------onTouchEvent-------: 2
08-11 13:33:27.962 11900-11900/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 2
08-11 13:33:27.962 11900-11900/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 2
08-11 13:33:27.962 11900-11900/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 2
08-11 13:33:27.962 11900-11900/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 2
08-11 13:33:27.962 11900-11900/com.ddz.lifestyle E/View---------onTouchEvent-------: 2
08-11 13:33:27.993 11900-11900/com.ddz.lifestyle E/activity-------dispatchTouchEvent-------: 1
08-11 13:33:27.994 11900-11900/com.ddz.lifestyle E/ViewGroup-------dispatchTouchEvent-------: 1
08-11 13:33:27.994 11900-11900/com.ddz.lifestyle E/ViewGroup-------onInterceptTouchEvent-------: 1
08-11 13:33:27.994 11900-11900/com.ddz.lifestyle E/View---------dispatchTouchEvent-------: 1
08-11 13:33:27.994 11900-11900/com.ddz.lifestyle E/View---------onTouchEvent-------: 1

分析:
1、手指按下:這次流程依然是Activity的dispatchTouchEvent分發(fā)事件給ViewGroup
2、VIewGroup的dispatchTouchEvent方法返回默認的super.dispatchTouchEvent(ev),所以事件繼續(xù)分發(fā),傳遞給onInterceptTouchEvent;
3、這時候onInterceptTouchEvent也默認不攔截,事件終于被傳遞給ViewGroup中的View了;
4、View接受到事件之后,dispatchTouchEvent方法也是返回默認super.dispatchTouchEvent(ev),事件傳遞給自己的onTouchEvent方法
5、View的onTouchEvent方法返回true,消費事件按下事件結(jié)束
6、手指移動:Activity已經(jīng)知道ViewGroup中的View的onTouchEvent方法要消費事件,手指移動事件就重復(fù)按下事件的流程,一直傳遞給View的onTouchEvent方法,直到事件被消費;
7、手指抬起:同手指移動一樣

總結(jié)

ViewGroup:

dispatchTouchEvent 分發(fā)
ViewGroup接收到事件之后,根據(jù)dispatchTouchEvent決定是否分發(fā)下去

  • 1、默認返回 super.dispatchTouchEvent(ev)方法,即默認分發(fā)事件
  • 2、如果返回false;事件將不再分發(fā),直接返回給上一層的onTouch方法,并且后面的事件將不再分發(fā)給當前ViewGroup,上層直接自己分發(fā)并消費掉
  • 3、如果返回true,事件將不再分發(fā)并且由ViewGroup的dispatchTouchEvent 消費掉,后面的觸摸事件也會同樣被ViewGroup的dispatchTouchEvent 消費

onInterceptTouchEvent 攔截
ViewGroup的dispatchTouchEvent如果默認將事件分發(fā)下去,傳遞給onInterceptTouchEvent方法,由onInterceptTouchEvent方法決定是否攔截

  • 1、默認返回super.onInterceptTouchEvent(ev) 即不攔截,事件繼續(xù)傳遞
  • 2、改為返回true,事件直接傳遞給ViewGroup的onTouchEvent方法消費,不再傳遞給ViewGroup中的View
  • 3、如果返回false,事件將傳遞給ViewGroup中的View去處理

onTouchEvent 消費
如果ViewGroup中的onInterceptTouchEvent 默認不攔截事件,這時根據(jù)ViewGroup的onTouchEvent返回值來判斷

  • 1、默認返回super.onTouchEvent(event),事件將傳遞給ViewGroup中的View進行處理,如果ViewGroup中View不消費事件,事件將會返回給ViewGroup的onTouchEvent方法處理,ViewGroup的onTouchEvent方法默認不處理,返回給上層的onTouchEvent方法處理
  • 2 、如果返回true,,事件也會傳遞給ViewGroup中的View進行處理,如果ViewGroup中View不消費事件,事件將會返回給ViewGroup的onTouchEvent方法,這時ViewGroup的onTouchEvent直接將事件消費掉,不返回上層的onTouchEvent方法了
  • 3、如果返回false,事件將默認由ViewGroup傳遞給View,View不處理又返回給ViewGroup的onTouchEvent,ViewGroup的onTouchEvent返回false,所以事件又返回給上層的onTouchEvent方法

View:

dispatchTouchEvent 分發(fā)
View接收到事件后,根據(jù)dispatchTouchEvent方法返回值,判斷是否繼續(xù)分發(fā)

  • 1、默認返回super.dispatchTouchEvent(ev),事件將分發(fā)下去,傳遞給View自己的onTouchEvent進行處理,
  • 2、如果返回false,事件將不分發(fā),直接返回給上層ViewGroup的onTouchEvent方法進行處理
  • 3、如果返回true,事件也不再分發(fā),直接由View的dispatchTouchEvent 進行消費,并且以后的事件同樣直接被View的dispatchTouchEvent 方法消費了

onTouchEvent 消費
如果View的dispatchTouchEvent 將事件傳遞給onTouchEvent方法,將根據(jù)onTouchEvent方法的返回值決定是否消費事件

  • 1、默認返回super.onTouchEvent(event),默認不消費事件,事件將返回給上層ViewGroup的onTouchEvent方法處理
  • 2、如果改為true,將事件消費,不再返回,以后其他事件同樣被onTouchEvent方法消費
  • 3 、如果改為false,同默認方法一樣,不再消費,返回給上層處理

所以,觸摸事件的所有流程已經(jīng)很清晰了

對于事件分發(fā):(dispatchTouchEvent)
如果想事件不向下傳遞,自己消費掉 :將當前的dispatchTouchEvent返回true;
如果想事件不向下傳遞,返回給上層 :將當前的dispatchTouchEvent返回false;
對于事件攔截:(onInterceptTouchEvent)
如果想攔截事件,給自己的onTouchEvent方法消費 :將onInterceptTouchEvent返回true
如果不攔截事件,默認向下傳遞 :將onInterceptTouchEvent返回false或者返回默認值
對于事件消費:(onTouchEvent)
如果不想消費,返回給上層 :將onTouchEvent返回默認或者返回false;
如果想消費,不再返回 :將onTouchEvent返回true;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容