Android触摸事件分发记录

背景简介

为了弄清Android的Touch事件分发流程,这里构造了一个Activity嵌套一个ViewGroup,再嵌套一个TextView,分别重写Activity的dispatchTouchEvent和onTouchEvent,重写ViewGroup的dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent,重写TextView的dispatchTouchEvent和onTouchEvent,通过改变不同Touch事件下这些方法的返回值,分析事件的流向。

都返回默认值

java 复制代码
public class MotionEventActivity extends AppCompatActivity {

    String TAG = "MotionPass";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        VG vg = new VG(this);
        vg.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        setContentView(vg);

        MyView myView = new MyView(this);
        myView.setText("111111111");
        FrameLayout.LayoutParams l = new FrameLayout.LayoutParams(UiUtils.dip2px(this,200),UiUtils.dip2px(this,200));
        l.setMargins(100,100,0,0);
        myView.setLayoutParams(l);
        myView.setBackgroundColor(getResources().getColor(android.R.color.holo_orange_light));
        vg.addView(myView);
    }

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

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


    public class VG extends FrameLayout{

        public VG(@NonNull Context context) {
            super(context);
        }


        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_MOVE");
                    //return true;
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }

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

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


    public class MyView extends androidx.appcompat.widget.AppCompatTextView{

        float downX;
        float downY;

        public MyView(Context context) {
            super(context);
        }

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

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //getParent().requestDisallowInterceptTouchEvent(true);
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    downX = event.getX();
                    downY = event.getY();
                    Log.d(TAG, "onTouchEvent:MyView ACTION_DOWN downX "+downX+" downY "+downY);
                    break;
                case MotionEvent.ACTION_MOVE:
                    float difX = downX - event.getX();
                    float difY = downY - event.getY();
                    Log.d(TAG, "onTouchEvent:MyView ACTION_MOVE difX "+difX+" difY "+difY);
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:MyView ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:MyView ACTION_CANCEL");
                    break;
            }
            return super.onTouchEvent(event);
        }

    }
}

触摸事件的流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 190.0 downY 162.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向

    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:VG->onTouchEvent:activity,ACTION_DOWN在VG和TextView中没有被拦截和消费,最终流回Activity。

  • ACTION_MOVE流向

    dispatchTouchEvent:activity->onTouchEvent:activity,因为ACTION_DOWN事件最终流回Activity,没有被消费,所以ACTION_MOVE直接从Activity的dispatchTouchEvent流向Actiity的onTouchEvent

  • ACTION_UP流向

    dispatchTouchEvent:activity->onTouchEvent:activity,同ACTION_MOVE。

在Activity的dispatchTouchEvent的action_down返回true

java 复制代码
@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_DOWN");
                return true;
                //break;
            case MotionEvent.ACTION_MOVE:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_UP");
                break;
            case MotionEvent.ACTION_CANCEL:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_CANCEL");
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity,ACTION_DOWN在Activity的dispatchTouchEvent中被拦截了,都没有流向Activity的onTouchEvent。
  • ACTION_MOVE流向
    dispatchTouchEvent:activity->onTouchEvent:activity,因为ACTION_DOWN事件在Activity的dispatchTouchEvent中截断了,没有被后续的控件消费,所以ACTION_MOVE直接从Activity的dispatchTouchEvent流向Actiity的onTouchEvent
  • ACTION_UP流向
    dispatchTouchEvent:activity->onTouchEvent:activity,同ACTION_MOVE。

在Activity的dispatchTouchEvent的action_move返回true

java 复制代码
@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_MOVE");
                return true;
                //break;
            case MotionEvent.ACTION_UP:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_UP");
                break;
            case MotionEvent.ACTION_CANCEL:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_CANCEL");
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 246.0 downY 241.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:VG->onTouchEvent:activity,ACTION_DOWN在VG和TextView中没有被拦截和消费,最终流回Activity。
  • ACTION_MOVE的流向
    dispatchTouchEvent:activity,ACTION_MOVE在Activity的dispatchTouchEvent中被拦截了,都没有流向Activity的onTouchEvent。
    • ACTION_UP流向
      dispatchTouchEvent:activity->onTouchEvent:activity

在Activity的dispatchTouchEvent的action_up返回true

java 复制代码
@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_UP");
                return true;
                //break;
            case MotionEvent.ACTION_CANCEL:
                Log.d(TAG, "dispatchTouchEvent:activity ACTION_CANCEL");
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 287.0 downY 277.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向

    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:VG->onTouchEvent:activity,ACTION_DOWN在VG和TextView中没有被拦截和消费,最终流回Activity。

  • ACTION_MOVE流向

    dispatchTouchEvent:activity->onTouchEvent:activity,因为ACTION_DOWN事件最终流回Activity,没有被消费,所以ACTION_MOVE直接从Activity的dispatchTouchEvent流向Actiity的onTouchEvent

  • ACTION_UP流向

    在Activity的dispatchTouchEvent中截断。

在Activity的onTouchEvent的action_down返回true

这种情况和都返回默认值是一样的

bash 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 222.0 downY 229.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

在Activity的onTouchEvent的action_move返回true

这种情况和都返回默认值是一样的

bash 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 222.0 downY 229.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

在Activity的onTouchEvent的action_up返回true

这种情况和都返回默认值是一样的

bash 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 222.0 downY 229.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

在VG的dispatchTouchEvent的action_down返回true

java 复制代码
@Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }

触摸事件的流向:

bash 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onTouchEvent:VG ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG,因为在VG的dispatchTouchEvent中action_down返回true,所以action_down在在VG的dispatchTouchEvent中就截断了,表示action_down在VG中被消费了。
  • ACTION_MOVE的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onTouchEvent:VG->onTouchEvent:activity,因为在VG的dispatchTouchEvent中action_down返回true,表示action_down被VG消费了,所以action_move就从activity直接流向VG并且不会走VG的onInterceptTouchEvent ,最后再流回activity。
    • ACTION_UP的流向
      action_up的流向和action_move一致。

在VG的dispatchTouchEvent的action_move返回true

java 复制代码
@Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_MOVE");
                    return true;
                    //break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "dispatchTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }

触摸事件流向:

bash 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 240.0 downY 208.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

这里和都返回默认值一样,因为action_down走了一圈又回到了activity的onTouchEvent,没有被消费,所以action_move直接从dispatchTouchEvent:activity->onTouchEvent:activity。

在VG的dispatchTouchEvent的action_up返回true

这里和在VG的dispatchTouchEvent的action_move返回true一样

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 243.0 downY 191.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

在VG的onInterceptTouchEvent的action_down返回true

java 复制代码
@Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onInterceptTouchEvent(ev);
        }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->onTouchEvent:VG->onTouchEvent:activity,在VG的onInterceptTouchEvent返回true,action_down事件被拦截到VG的onTouchEvent中,但是没有被消费,又流回了activity的onTouchEvent。
    由于action_down事件没有被消费,流了一圈又回到activity的onTouchEvent,所以action_move直接从dispatchTouchEvent:activity->onTouchEvent:activity,action_up也一样。

在VG的onInterceptTouchEvent的action_down返回true,同时在VG的onTouchEvent的action_down返回true

java 复制代码
@Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onInterceptTouchEvent(ev);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onTouchEvent:VG ACTION_MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onTouchEvent(event);
        }

触摸事件的流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
onTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onTouchEvent:VG ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->onTouchEvent:VG,action_down在VG的onInterceptTouchEvent中被拦截,在VG的onTouchEvent中被消费
  • ACTION_MOVE的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onTouchEvent:VG->onTouchEvent:activity,由于action_down在VG的onTouchEvent中被消费,所以action_move不用再走VG的onInterceptTouchEvent,会直接流入VG的onTouchEvent,但是没有被消费,又流回activity的onTouchEvent,action_up也是如此

在VG的onInterceptTouchEvent的action_down返回true,同时在VG的onTouchEvent的action_down和action_move返回true

java 复制代码
@Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onInterceptTouchEvent(ev);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onTouchEvent:VG ACTION_MOVE");
                    return true;
                    //break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onTouchEvent(event);
        }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
onTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onTouchEvent:VG ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->onTouchEvent:VG,action_down在VG的onInterceptTouchEvent中被拦截,在VG的onTouchEvent中被消费
  • ACTION_MOVE的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onTouchEvent:VG,由于action_down在VG的onTouchEvent中被消费,所以action_move不用再走VG的onInterceptTouchEvent,会直接流入VG的onTouchEvent,并且在VG的onTouchEvent中被消费
  • ACTION_up的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onTouchEvent:VG->onTouchEvent:activity

在VG的onInterceptTouchEvent的action_move返回true

java 复制代码
@Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_DOWN");
                    //return true;
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_MOVE");
                    return true;
                    //break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onInterceptTouchEvent(ev);
        }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 173.0 downY 155.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

和都返回默认一样

在VG的onInterceptTouchEvent的action_up返回true

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 173.0 downY 155.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

和都返回默认一样

在VG的onTouchEvent的action_down返回true

java 复制代码
@Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onTouchEvent:VG ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onTouchEvent:VG ACTION_MOVE");
                    //return true;
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onTouchEvent(event);
        }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 264.0 downY 181.0
onTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onTouchEvent:VG ACTION_UP
onTouchEvent:activity ACTION_UP

在VG的onTouchEvent的action_move返回true

java 复制代码
@Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onTouchEvent:VG ACTION_DOWN");
                    //return true;
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onTouchEvent:VG ACTION_MOVE");
                    return true;
                    //break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onTouchEvent(event);
        }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 239.0 downY 171.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

和默认返回一样

在VG的onTouchEvent的action_up返回true

和默认返回一样

在MyView的dispatchTouchEvent的action_down返回true

java 复制代码
@Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_DOWN");
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_CANCEL");
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }

触摸事件的流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onInterceptTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:MyView ACTION_MOVE
onTouchEvent:MyView ACTION_MOVE difX -257.0 difY -144.35352
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onInterceptTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:MyView ACTION_MOVE
onTouchEvent:MyView ACTION_MOVE difX -257.0 difY -145.0
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onInterceptTouchEvent:VG ACTION_UP
dispatchTouchEvent:MyView ACTION_UP
onTouchEvent:MyView ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView,action_down在MyView的dispatchTouchEvent中被截断,意味着action_down在MyView的dispatchTouchEvent中被消费掉了。
  • ACTION_MOVE的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:activity,由于action_down在MyView的dispatchTouchEvent中被消费,所以action_move也会流向MyView的onTouchEvent,但是MyView的onTouchEvent没有消费action_move,所以action_move最终流回activity,但是不会经过VG的onTouchEvent
  • ACTION_up的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:activity,和action_move一样

在MyView的dispatchTouchEvent的action_move返回true

java 复制代码
 @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_MOVE");
                    return true;
                    //break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "dispatchTouchEvent:MyView ACTION_CANCEL");
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }

触摸事件流向

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 209.0 downY 153.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

和都返回默认一样

在MyView的dispatchTouchEvent的action_up返回true

和都返回默认一样

在MyView的onTouchEvent的action_down返回true

java 复制代码
@Override
        public boolean onTouchEvent(MotionEvent event) {
            //getParent().requestDisallowInterceptTouchEvent(true);
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    downX = event.getX();
                    downY = event.getY();
                    Log.d(TAG, "onTouchEvent:MyView ACTION_DOWN downX "+downX+" downY "+downY);
                    return true;
                    //break;
                case MotionEvent.ACTION_MOVE:
                    float difX = downX - event.getX();
                    float difY = downY - event.getY();
                    Log.d(TAG, "onTouchEvent:MyView ACTION_MOVE difX "+difX+" difY "+difY);
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:MyView ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:MyView ACTION_CANCEL");
                    break;
            }
            return super.onTouchEvent(event);
        }

触摸事件流向:

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 242.0 downY 123.0
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onInterceptTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:MyView ACTION_MOVE
onTouchEvent:MyView ACTION_MOVE difX 0.8671875 difY -1.0
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onInterceptTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:MyView ACTION_MOVE
onTouchEvent:MyView ACTION_MOVE difX 1.0 difY -1.0
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onInterceptTouchEvent:VG ACTION_UP
dispatchTouchEvent:MyView ACTION_UP
onTouchEvent:MyView ACTION_UP
onTouchEvent:activity ACTION_UP
  • ACTION_DOWN的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView,action_down在MyView的onTouchEvent中被截断,意味着action_down在MyView的onTouchEvent中被消费掉了。
  • ACTION_MOVE的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:activity,由于action_down在MyView的onTouchEvent中被消费,所以action_move也会流向MyView的onTouchEvent,但是MyView的onTouchEvent没有消费action_move,所以action_move最终流回activity,但是不会经过VG的onTouchEvent
  • ACTION_up的流向
    dispatchTouchEvent:activity->dispatchTouchEvent:VG->onInterceptTouchEvent:VG->dispatchTouchEvent:MyView->onTouchEvent:MyView->onTouchEvent:activity,和action_move一样

在MyView的onTouchEvent的action_move返回true

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 247.0 downY 161.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

和都返回默认一样

在MyView的onTouchEvent的action_up返回true

powershell 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 247.0 downY 161.0
onTouchEvent:VG ACTION_DOWN
onTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
onTouchEvent:activity ACTION_UP

和都返回默认一样

阶段总结

  • action_down事件在哪个View被消费,也就是不管是在View的dispatchTouchEvent方法还是onTouchEvent方法返回true,那么对应的同一个事件序列的action_move也会流到这个View的onTouchEvent
  • action_down事件在ViewGroup被消费,也就是ViewGroup的dispatchTouchEvent方法还是onTouchEvent方法返回true,那么对应的同一个事件序列的action_move也会流到这个ViewGroup的onTouchEvent,而且action_move会跳过这个ViewGroup的onInterceptTouchEvent方法
  • action_down事件在View被消费,也就是不管是在View的dispatchTouchEvent方法还是onTouchEvent方法返回true,那么同一个事件序列的action_move会流经这个View的父View(直接或间接)的onInterceptTouchEvent方法,父View可以在onInterceptTouchEvent中对需要的action_move进行拦截,并在父View的onTouchEvent中进行处理
  • 子View想要收到触摸事件,必须把action_down事件消费掉,也就是action_down在View的dispatchTouchEvent还是onTouchEvent返回true,当然最好是onTouchEvent,否则子View无法接收到后续的触摸事件。

在MyView的onTouchEvent返回true,在VG的onInterceptTouchEvent的action_move返回true。

java 复制代码
@Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            float downY = ev.getY();
            switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_MOVE");
//                    if (downY > 100 && downY < 100+UiUtils.dip2px(MotionEventActivity.this,100)){
//                        return true;
//                    }
                    return true;
                    //break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onInterceptTouchEvent:VG ACTION_CANCEL");
                    break;
            }
            return super.onInterceptTouchEvent(ev);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //getParent().requestDisallowInterceptTouchEvent(true);
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    downX = event.getX();
                    downY = event.getY();
                    Log.d(TAG, "onTouchEvent:MyView ACTION_DOWN downX "+downX+" downY "+downY);
                    //return true;
                    break;
                case MotionEvent.ACTION_MOVE:
                    float difX = downX - event.getX();
                    float difY = downY - event.getY();
                    Log.d(TAG, "onTouchEvent:MyView ACTION_MOVE difX "+difX+" difY "+difY);
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent:MyView ACTION_UP");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "onTouchEvent:MyView ACTION_CANCEL");
                    break;
            }
            return true;
            //return super.onTouchEvent(event);
        }

触摸事件的流向:

bash 复制代码
dispatchTouchEvent:activity ACTION_DOWN
dispatchTouchEvent:VG ACTION_DOWN
onInterceptTouchEvent:VG ACTION_DOWN
dispatchTouchEvent:MyView ACTION_DOWN
onTouchEvent:MyView ACTION_DOWN downX 216.0 downY 161.0
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onInterceptTouchEvent:VG ACTION_MOVE
dispatchTouchEvent:MyView ACTION_CANCEL
onTouchEvent:MyView ACTION_CANCEL
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:VG ACTION_MOVE
onTouchEvent:VG ACTION_MOVE
onTouchEvent:activity ACTION_MOVE
dispatchTouchEvent:activity ACTION_UP
dispatchTouchEvent:VG ACTION_UP
onTouchEvent:VG ACTION_UP
onTouchEvent:activity ACTION_UP
相关推荐
aaajj2 小时前
【Android】声控拍照例子
android
stevenzqzq2 小时前
Android MVI 中 setState(reduce: State.() -> State) 设计说明文档
android·mvi框架
鸣弦artha2 小时前
Flutter框架跨平台鸿蒙开发——InheritedWidget基础使用-计数器案例
android·flutter·harmonyos
嵌入式-老费2 小时前
Android开发(开发板的三种操作系统)
android
凛_Lin~~3 小时前
安卓网络框架——OkHttp源码解析(基于3.14.x)
android·网络·okhttp
stevenzqzq3 小时前
android SharedFlow和Channel比较
android·channel·sharedflow
zhangphil4 小时前
Kotlin实现Glide/Coil图/视频加载框架(二)
android·kotlin
shughui4 小时前
APP、Web、H5、iOS与Android的区别及关系
android·前端·ios
千里马学框架4 小时前
敏感权限如何自动授权?pkms的permission部分常用命令汇总
android·车载系统·framework·perfetto·权限·系统开发·pkms