Skip to content

Latest commit

 

History

History
930 lines (656 loc) · 39.9 KB

事件分发.md

File metadata and controls

930 lines (656 loc) · 39.9 KB

前言

//可能是我们村写的最好的

一直对Android事件分发的问题,搞的云里雾里的,正所谓念念不忘,必有回响,今日得空,整理一个文章

demo程序很简单,AMainActivity设置了一个简单的layout,BViewGroupxxx继承自 ViewGroup,CView继承自 View.

对于事件分发,各个类都包含了几个重要的方法。

Activity中包含了两个重要的方法

dispatchTouchEvent
onTouchEvent

ViewGroup 中包含了三个重要的方法

dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent

View 中包含了两个重要的方法

dispatchTouchEvent
onTouchEvent

对于类名以及log出现的多个'x',主要是为了打印日志的长度一致,方便分析

AMainActivity
BViewGroupxxx
CViewxxxxxxxx

dispatchTouchEventxxx
onInterceptTouchEvent
onTouchEventxxxxxxxxx

Layout

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

    <com.vphealthy.viewgroupdemo.BViewGroupxxx
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@color/colorPrimary">

        <com.vphealthy.viewgroupdemo.CViewxxxxxxxx
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@color/colorAccent" />
        
    </com.vphealthy.viewgroupdemo.BViewGroupxxx>

</LinearLayout>

AMainActivity

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "dispatchTouchEventxxx ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i(TAG, "dispatchTouchEventxxx ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i(TAG, "dispatchTouchEventxxx ACTION_UP");
            break;
    }
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_UP");
            break;
    }
    return super.onTouchEvent(ev);
}

BViewGroupxxx

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "dispatchTouchEventxxx ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i(TAG, "dispatchTouchEventxxx ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i(TAG, "dispatchTouchEventxxx ACTION_UP");
            break;
    }
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "onInterceptTouchEvent ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i(TAG, "onInterceptTouchEvent ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i(TAG, "onInterceptTouchEvent ACTION_UP");
            break;
    }
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_UP");
            break;
    }
    return super.onTouchEvent(ev);
}

CViewxxxxxxxx

	@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "dispatchTouchEventxxx ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "dispatchTouchEventxxx ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG, "dispatchTouchEventxxx ACTION_UP");
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

	@Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG, "onTouchEventxxxxxxxxx ACTION_UP");
                break;
        }
        return super.onTouchEvent(event);
    }

以下所有的操作都只是一种,按下->移动->抬起

#针对View的分析

情况A(只针对View.onTouchEvent【super,false,true】)

情况A.1

可以看到当我们所有的事件回复都是super时,

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回super,

日志如下

//Down事件	 
15:42:41.720 25128-25128/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
15:42:41.721 25128-25128/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
15:42:41.721 25128-25128/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
15:42:41.721 25128-25128/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_DOWN
15:42:41.721 25128-25128/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_DOWN
15:42:41.721 25128-25128/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_DOWN
15:42:41.721 25128-25128/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_DOWN
//MOVE事件
15:50:09.583 25376-25376/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
15:50:08.566 25376-25376/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_MOVE
//UP事件
15:42:41.763 25128-25128/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
15:42:41.763 25128-25128/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_UP

Down事件的流程是 Activity->ViewGroup->View->ViewGroup->Activity,

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx->BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 CViewxxxxxxxx.dispatchTouchEventxxx->CViewxxxxxxxx.onTouchEventxxxxxxxxx

日志传递流程是 BViewGroupxxx.onTouchEventxxxxxxxxx

日志传递流程是 AMainActivity.onTouchEventxxxxxxxxx

UP&move事件则只在MainActivity中处理,为什么不传递给ViewGroup->View?

当Down传递到View.onTouchEvent,不View被消费时,还会回传到ViewGroup.onTouchEvent,MainActivity.onTouchEvent,

并且后续的MOVE,UP事件也不会再传递给ViewGroup和View了。

问题一 后续的MOVE,UP事件不会再传递给ViewGroup和View?

情况A.2

现在我们将View中的onTouchEvent方法返回false,其他均为super,与(A.1)的现象一致。

情况A.3

现在我们将View中的onTouchEvent方法返回true,其他均为super。

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,

日志如下

//Down事件	
15:52:52.666 25944-25944/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
15:52:52.667 25944-25944/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
15:52:52.667 25944-25944/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
15:52:52.667 25944-25944/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_DOWN
15:52:52.667 25944-25944/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_DOWN
//MOVE事件	
15:52:52.685 25944-25944/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
15:52:52.685 25944-25944/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_MOVE
15:52:52.685 25944-25944/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_MOVE
15:52:52.685 25944-25944/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_MOVE
15:52:52.685 25944-25944/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_MOVE
//UP事件	
15:52:53.226 25944-25944/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
15:52:53.226 25944-25944/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_UP
15:52:53.226 25944-25944/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_UP
15:52:53.226 25944-25944/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_UP
15:52:53.226 25944-25944/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_UP

Down事件的流程是 MainActivity->ViewGroup->View

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx->BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 CViewxxxxxxxx.dispatchTouchEventxxx->CViewxxxxxxxx.onTouchEventxxxxxxxxx

UP&move事件也同于Down事件

这里与(A.1)相比就发现了2个区别

1.View.onTouchEvent返回ture以后,ViewGroup.onTouchEvent以及Activity.onTouchEvent不会再调用了

2.View.onTouchEvent返回ture以后,down和move方法不只在Activity执行了,也会分发给ViewGroup和View

情况A.4

现在我们将ViewGroup中的onTouchEvent方法返回true,其他均super。

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回true,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回super,

日志如下

//Down事件	
17:51:40.790 2159-2159/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
17:51:40.791 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
17:51:40.791 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
17:51:40.791 2159-2159/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_DOWN
17:51:40.791 2159-2159/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_DOWN
17:51:40.791 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_DOWN
//MOVE事件	
17:51:40.798 2159-2159/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
17:51:40.798 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_MOVE
17:51:40.798 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_MOVE
//up事件
17:51:41.007 2159-2159/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
17:51:41.007 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_UP
17:51:41.007 2159-2159/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_UP

Down事件的流程是 MainActivity->ViewGroup->View

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx->BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 CViewxxxxxxxx.dispatchTouchEventxxx->CViewxxxxxxxx.onTouchEventxxxxxxxxx->BViewGroupxxx.onTouchEventxxxxxxxxx

UP&move事件则不同于Down事件

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx->BViewGroupxxx.onTouchEventxxxxxxxxx,

发现了么,BViewGroupxxx.onInterceptTouchEvent不调用了,直接就调用了BViewGroupxxx.onTouchEventxxxxxxxxx,子类的onTouchEventxxxxxxxxx返回super,即不处理时,BViewGroupxxx的UP&move事件的onInterceptTouchEvent都不分发了?

问题二 BViewGroupxxx的UP&move事件的onInterceptTouchEvent为什么不分发了

情况A结论

当Activity,ViewGroup 返回均为super时且View的dispatchTouchEvent返回super时,

只有View的onTouchEvent返回ture;之后的move及up事件才会再传给view.

当Activity,ViewGroup,View返回均为super时,只有ViewGroup的onTouch返回true, BViewGroupxxx后续的UP&move事件的onInterceptTouchEvent都不分发了?

情况B(针对View.dispatchTouchEvent【true】和View.onTouchEvent【super,false,true】)

情况B.1

现在我们将View中的dispatchTouchEvent也返回true,onTouchEvent方法返回true,其他均为super。

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回true,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,

日志如下

//Down事件		
16:12:50.244 27405-27405/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
16:12:50.245 27405-27405/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
16:12:50.245 27405-27405/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
16:12:50.245 27405-27405/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_DOWN
//MOVE事件	
16:12:50.499 27405-27405/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
16:12:50.500 27405-27405/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_MOVE
16:12:50.500 27405-27405/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_MOVE
16:12:50.500 27405-27405/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_MOVE
//UP事件	
16:12:50.680 27405-27405/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
16:12:50.681 27405-27405/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_UP
16:12:50.681 27405-27405/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_UP
16:12:50.681 27405-27405/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_UP

Down事件的流程是 MainActivity->ViewGroup->View

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx->BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 CViewxxxxxxxx.dispatchTouchEventxxx

UP&move事件也同于Down事件

这里与情况与(A.3)相比就发现了1个区别

1.当事件传递到View.dispatchTouchEvent返回ture时,View.onTouchEvent不会再被执行,

情况B.2

现在我们将View中的dispatchTouchEvent返回true,View.onTouchEvent方法返回false,其他均super。

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回true,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回false,

日志与(B.1)的现象一致。

情况B.3

现在我们将View中的dispatchTouchEvent返回true,其他均为super。

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回true,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,

日志与(B.1)的现象一致。

情况B结论

现在我们将View中的dispatchTouchEvent返回true时,表示事件被View.dispatchTouchEvent消费,

View.onTouchEvent无论返回什么都不会被调用。

原因可以在View.java的源码可以找到

public boolean dispatchTouchEvent(MotionEvent event) {
    // If the event should be handled by accessibility focus first.
    if (event.isTargetAccessibilityFocus()) {
        // We don't have focus or no virtual descendant has it, do not handle the event.
        if (!isAccessibilityFocusedViewOrHost()) {
            return false;
        }
        // We have focus and got the event, then use normal event dispatch.
        event.setTargetAccessibilityFocus(false);
    }

    boolean result = false;
	....
    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;
        }
    }
	....
}

当CViewxxxxxxxx的dispatchTouchEvent不调用super.dispatchTouchEvent时,

View的onTouchEvent当然不会被执行,

View的onTouchEvent不被执行,CViewxxxxxxxx.onTouchEvent形同虚设

情况C(针对View.dispatchTouchEvent【false】和View.onTouchEvent【super,false,true】)

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回false,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回super,

--

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回false,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回false,

--

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

CViewxxxxxxxx.dispatchTouchEventxxx 返回false,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,

由情况B得出的结论,当CViewxxxxxxxx的dispatchTouchEvent返回false时,CViewxxxxxxxx.onTouchEvent也是形同虚设,我们来看一下会发生什么

//Down事件		
19:09:03.318 4794-4794/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
19:09:03.319 4794-4794/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
19:09:03.319 4794-4794/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
19:09:03.319 4794-4794/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_DOWN
19:09:03.319 4794-4794/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_DOWN
19:09:03.319 4794-4794/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_DOWN
//MOVE事件		
19:09:03.350 4794-4794/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
19:09:03.350 4794-4794/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_MOVE
//UP事件	
19:09:03.503 4794-4794/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
19:09:03.503 4794-4794/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_UP

Down事件的流程是 Activity->ViewGroup->View->ViewGroup->Activity,

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx->BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 CViewxxxxxxxx.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.onTouchEventxxxxxxxxx

日志传递流程是 AMainActivity.onTouchEventxxxxxxxxx

UP&move事件则只在MainActivity中处理,为什么不传递给ViewGroup->View?

问题三 当CViewxxxxxxxx的dispatchTouchEvent返回false时,如何调用上一层的onTouchEventxxxxxxxxx

这时我们发现了跟(情况A.1)的现象很相似,不同的在于CViewxxxxxxxx.dispatchTouchEventxxx后,不再执行CViewxxxxxxxx.onTouchEventxxxxxxxxx

针对View的总结

Activity及ViewGroup均为super,修改View的可能存在的9种情况

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,

		
CViewxxxxxxxx.dispatchTouchEventxxx[super]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [super]
	说明:CViewxxxxxxxx.onTouchEventxxxxxxxxx(down)会被调用,且再向BViewGroupxxx及AMainActivity回溯onTouchEventxxxxxxxxx,
	Move,Up事件只在AMainActivity才会有回调,不会分发到BViewGroupxxx及CViewxxxxxxxx,

	CViewxxxxxxxx.onTouchEventxxxxxxxxx [false]
	说明:CViewxxxxxxxx.onTouchEventxxxxxxxxx(down)会被调用,且再向BViewGroupxxx及AMainActivity回溯onTouchEventxxxxxxxxx,
	Move,Up事件只在AMainActivity才会有回调,不会分发到BViewGroupxxx及CViewxxxxxxxx,

	CViewxxxxxxxx.onTouchEventxxxxxxxxx [true]
	说明:CViewxxxxxxxx.onTouchEventxxxxxxxxx(down,move,up)均会被调用,然后结束,
	不会再向BViewGroupxxx及AMainActivity回溯onTouchEventxxxxxxxxx


CViewxxxxxxxx.dispatchTouchEventxxx[true]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [super]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [false]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [true]
	说明:CViewxxxxxxxx.onTouchEventxxxxxxxxx(down,move,up)均不会被调用,
	Down,Move,Up事件最终会分发到CViewxxxxxxxx.dispatchTouchEventxxx,然后结束,
	不会再向BViewGroupxxx及AMainActivity回溯onTouchEventxxxxxxxxx

CViewxxxxxxxx.dispatchTouchEventxxx[false]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [super]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [false]
	CViewxxxxxxxx.onTouchEventxxxxxxxxx [true]
	说明:CViewxxxxxxxx.onTouchEventxxxxxxxxx(down,move,up)均不会被调用,
	Down事件最终会分发到CViewxxxxxxxx.dispatchTouchEventxxx,然后结束,
	Move,Up事件只在AMainActivity才会有回调,不会分发到BViewGroupxxx.dispatchTouchEventxxx

View的操作分析结束了,接着我们来分析ViewGroup的处理。

到此我们明白了事件处理的2个原则

1.dispatchTouchEvent是用于自上而下的分发事件,
只有当返回super时,才会被分发到下一步;
返回ture时,所有事件被自己消费;
返回false时,会回溯给自己上一层的对象的onTouchEvent去处理

2.onTouchEvent的事件消费是自下而上的,下面不消费就一直向上传递,直到被消费才中止。

3.由Down事件的消费情况来确定了消费的目标对象,再来判断之后的move,up的事件,要具体分发到哪里

针对ViewGroup的分析

情况D.1 BViewGroupxxx.dispatchTouchEventxxx 返回true

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,
表示事件会在Activity正常分发

BViewGroupxxx.dispatchTouchEventxxx 返回true, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,
表示事件会在viewGroup不会被分发,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,
表示事件会在view正常分发且消费

根据view的情况可以猜想,Activity的事件只会分发到ViewGroup的dispatchTouchEvent,然后不再走ViewGroup.onInterceptTouchEvent及ViewGroup.onTouchEvent,因为被ViewGroup的dispatchTouchEvent消费了,也不会回溯到Activity的onTouchEvent

//Down事件
10:09:55.691 7736-7736/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
10:09:55.692 7736-7736/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
//Move事件	
10:09:55.822 7736-7736/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
10:09:55.822 7736-7736/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_MOVE
//UP事件	
10:09:56.540 7736-7736/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
10:09:56.540 7736-7736/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_UP

根据日志情况来看,与我们猜想的一致

情况D.2 BViewGroupxxx.dispatchTouchEventxxx 返回false

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,
表示事件会在Activity正常分发

BViewGroupxxx.dispatchTouchEventxxx 返回false, 
BViewGroupxxx.onInterceptTouchEvent 返回super, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,
表示事件会在viewGroup不会被分发,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,
表示事件会在view正常分发且消费

根据view的情况可以猜想,Activity的事件只会分发到ViewGroup的dispatchTouchEvent,然后不再走ViewGroup.onInterceptTouchEvent及ViewGroup.onTouchEvent,因为没有被ViewGroup的dispatchTouchEvent消费,所以会回溯到Activity的onTouchEvent,且后续的Move,Up事件只在AMainActivity才会有回调,不会分发到BViewGroupxxx.dispatchTouchEventxxx

//Down事件
10:17:32.941 8054-8054/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
10:17:32.942 8054-8054/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
10:17:32.942 8054-8054/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_DOWN
//Move事件	
10:17:33.106 8054-8054/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
10:17:33.106 8054-8054/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_MOVE
//Up事件
10:17:33.519 8054-8054/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
10:17:33.519 8054-8054/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_UP

根据日志情况来看,与我们猜想的一致

情况E.1 BViewGroupxxx.onInterceptTouchEvent 返回false

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,
表示事件会在Activity正常分发

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回false, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,
表示事件会在viewGroup不会被分发,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,
表示事件会在view正常分发且消费

我们看下会发生什么

//Down事件
10:31:17.620 8753-8753/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
10:31:17.620 8753-8753/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
10:31:17.620 8753-8753/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
10:31:17.620 8753-8753/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_DOWN
10:31:17.620 8753-8753/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_DOWN
//Move事件
10:31:17.645 8753-8753/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
10:31:17.645 8753-8753/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_MOVE
10:31:17.645 8753-8753/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_MOVE
10:31:17.645 8753-8753/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_MOVE
10:31:17.645 8753-8753/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_MOVE
//Up事件
10:31:18.062 8753-8753/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
10:31:18.062 8753-8753/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_UP
10:31:18.062 8753-8753/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_UP
10:31:18.062 8753-8753/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: dispatchTouchEventxxx ACTION_UP
10:31:18.062 8753-8753/com.vphealthy.viewgroupdemo I/CViewxxxxxxxx: onTouchEventxxxxxxxxx ACTION_UP

我们发现所有的事件(Down,Move,Up)都经过了三个类的的方法,与(针对View的分析中的情况A.4)结果一致,而在前者中,BViewGroupxxx.onInterceptTouchEvent的返回值为super,这也说明BViewGroupxxx.onInterceptTouchEvent的返回值为(false或super时),现象是一致。

这点可以从ViewGroup.onInterceptTouchEvent的源码中得知

public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
            && ev.getAction() == MotionEvent.ACTION_DOWN
            && ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
            && isOnScrollbarThumb(ev.getX(), ev.getY())) {
        return true;
    }
    return false;
}

ViewGroup.onInterceptTouchEvent默认返回的就是false,那么调用super,返回的不就是false么,故ViewGroup.onInterceptTouchEvent返回false或super时,现象一致。

情况E.2 BViewGroupxxx.onInterceptTouchEvent 返回true

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,
表示事件会在Activity正常分发

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回true, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,
表示事件会在viewGroup不会被分发,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,
表示事件会在view正常分发且消费

到目前为止,我们还不清楚当事件被ViewGroup拦截会发生什么

//Down事件
10:53:23.939 10154-10154/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
10:53:23.940 10154-10154/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
10:53:23.940 10154-10154/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
10:53:23.940 10154-10154/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_DOWN
10:53:23.940 10154-10154/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_DOWN
//Move事件
10:53:24.028 10154-10154/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
10:53:24.028 10154-10154/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_MOVE
//UP事件
10:53:24.218 10154-10154/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
10:53:24.218 10154-10154/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_UP

Down事件的流程是 Activity->ViewGroup->Activity,

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 BViewGroupxxx.onTouchEventxxxxxxxxx

日志传递流程是 AMainActivity.onTouchEventxxxxxxxxx

发现了没有,这里根本没有CViewxxxxxxxx的事情,被BViewGroupxxx拦截之后,直接传递给BViewGroupxxx.onTouchEventxxxxxxxxx,并且返回的是super,所以还会向上回溯,返回给AMainActivity

Move,Up及事件只在AMainActivity传递

情况F.1 BViewGroupxxx.onInterceptTouchEvent 返回true,BViewGroupxxx.onTouchEventxxxxxxxxx返回true

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,
表示事件会在Activity正常分发

BViewGroupxxx.dispatchTouchEventxxx 返回super, 
BViewGroupxxx.onInterceptTouchEvent 返回true, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回true,
表示事件会在viewGroup不会被分发,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super,
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true,
表示事件会在view正常分发且消费

到目前为止,我们还不清楚当事件被ViewGroup拦截会发生什么

//Down事件
11:08:43.132 10592-10592/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
11:08:43.133 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
11:08:43.133 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
11:08:43.133 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_DOWN
//Move事件
11:08:43.156 10592-10592/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
11:08:43.156 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_MOVE
11:08:43.156 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_MOVE
//Up事件
11:08:43.357 10592-10592/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
11:08:43.357 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_UP
11:08:43.357 10592-10592/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_UP

Down事件的流程是 Activity->ViewGroup->Activity,

日志传递流程是 AMainActivity.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.dispatchTouchEventxxx

日志传递流程是 BViewGroupxxx.onInterceptTouchEvent

日志传递流程是 BViewGroupxxx.onTouchEventxxxxxxxxx

发现了没有,Down事件不会回溯给AMainActivity了,因为已经被BViewGroupxxx.onTouchEventxxxxxxxxx消费了,所以不再回溯

Move,Up及事件也会传递给BViewGroupxxx,不同的在于不会再调用了onInterceptTouchEvent?

情况F.2 BViewGroupxxx.onInterceptTouchEvent 返回true,BViewGroupxxx.onTouchEventxxxxxxxxx返回false

//Down事件
11:23:23.161 10836-10836/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
11:23:23.162 10836-10836/com.vphealthy.viewgroupdemo I/BViewGroupxxx: dispatchTouchEventxxx ACTION_DOWN
11:23:23.162 10836-10836/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onInterceptTouchEvent ACTION_DOWN
11:23:23.162 10836-10836/com.vphealthy.viewgroupdemo I/BViewGroupxxx: onTouchEventxxxxxxxxx ACTION_DOWN
11:23:23.162 10836-10836/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_DOWN
//Move事件
11:23:23.172 10836-10836/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
11:23:23.172 10836-10836/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_MOVE
//Up事件
11:23:23.315 10836-10836/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP
11:23:23.316 10836-10836/com.vphealthy.viewgroupdemo I/AMainActivity: onTouchEventxxxxxxxxx ACTION_UP

到这已经没有什么好说的了,因为BViewGroupxxx.onTouchEventxxxxxxxxx返回false,也就是说BViewGroupxxx.onTouchEventxxxxxxxxx不消费事件,那么Down事件要回溯给AMainActivity.onTouchEventxxxxxxxxx,且后续的move,up事件,不会再给BViewGroupxxx了。

#针对ViewGroup的分析总结

至此我们的分析涉及了以下的多种情况

AMainActivity.dispatchTouchEventxxx 返回super
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super,true,false, 
BViewGroupxxx.onInterceptTouchEvent 返回super,true,false, 
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super,true,false,

CViewxxxxxxxx.dispatchTouchEventxxx 返回super
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true

我们可以得到以下的结论

当ViewGroup的dispatchTouchEvent返回true时,与View的dispatchTouchEvent处理一致,都是交给自己处理,不会再分发了。
当ViewGroup的onInterceptTouchEvent返回true时,会传递给ViewGroup的onTouchEvent去处理
ViewGroup的onTouchEvent的处理与View的onTouchEvent的处理一致,
从源码可知,其实ViewGroup就是继承View的,且ViewGroup并没有复写onTouchEvent方法

针对Activty的分析

情况G.1 AMainActivity.dispatchTouchEventxxx 返回true

AMainActivity.dispatchTouchEventxxx 返回true
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super
BViewGroupxxx.onInterceptTouchEvent 返回super
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super

CViewxxxxxxxx.dispatchTouchEventxxx 返回super
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true

看看会发生什么

11:39:26.814 11282-11282/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
11:39:26.926 11282-11282/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
11:39:27.177 11282-11282/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
11:39:27.177 11282-11282/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP

事件少的可怜,所有的事件都只在AMainActivity: dispatchTouchEventxxx中调用,不分发给自己BViewGroupxxx.dispatchTouchEventxxx 以及AMainActivity: onTouchEventxxxxxxxxx,

情况G.2 AMainActivity.dispatchTouchEventxxx 返回false

AMainActivity.dispatchTouchEventxxx 返回false
AMainActivity.onTouchEventxxxxxxxxx 返回super,

BViewGroupxxx.dispatchTouchEventxxx 返回super
BViewGroupxxx.onInterceptTouchEvent 返回super
BViewGroupxxx.onTouchEventxxxxxxxxx 返回super

CViewxxxxxxxx.dispatchTouchEventxxx 返回super
CViewxxxxxxxx.onTouchEventxxxxxxxxx 返回true

看看会发生什么

11:42:10.812 12416-12416/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_DOWN
11:42:10.921 12416-12416/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
11:42:10.985 12416-12416/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_MOVE
11:42:10.985 12416-12416/com.vphealthy.viewgroupdemo I/AMainActivity: dispatchTouchEventxxx ACTION_UP

哈哈,本来以为会调用onTouchEvent,但是发现了跟情况G.1一致,
仔细想想也是,按照之前的现象分析,当Activity.dispatchTouchEvent返回false时,
应该给上一层的onTouchEvent去处理,可是Activity已经是最上层了,哪里还有onTouchEvent给它调用呢。

对于Activity.onTouchEvent的返回值其实没有讨论的必要性,因为已经是最上层了,返回什么都不重要了。

至此,涉及Activity,ViewGroup,View事件的所有情况,我们都将日志打印分析了一遍。

问题整理

问题一 当所有都返回super时,UP&move事件则只在MainActivity中处理,为什么不传递给ViewGroup->View?
问题二 当Activity,ViewGroup,View返回均为super时,只有ViewGroup的onTouch返回true,
	   ViewGroup后续的UP&move事件的onInterceptTouchEvent都不分发了?
问题三 当CViewxxxxxxxx的dispatchTouchEvent返回false时,如何调用上一层的onTouchEventxxxxxxxxx

答案都在viewgroup中的dispatchTouchEvent的方法中