onresize事件会被多次触发_事件分发(一)Activity对触摸事件的分发流程

4e0c2590867250ce74d625e3e51ce145.png

Activity对触摸事件的分发流程

事件解释ACTION_DOWN手指初次接触到屏幕时触发ACTION_MOVE手指在屏幕上滑动时触发,会多次触发ACTION_UP手指离开屏幕时触发ACTION_CANCEL事件被上层拦截时触发

本文源码基于Android 10.0

首先,用户触摸屏幕之后,会调用Activity的dispatchTouchEvent()方法:

ViewDispatchActivity.java

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Log.e("ViewDispatchActivity", "dispatchTouchEvent");
    return super.dispatchTouchEvent(ev);
}

也就是: Activity.java

public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

以上可知:

Activity.onUserInteraction()

1、如果事件类型为ACTION_DOWN按下操作,则会回调onUserInteraction()方法,表示用户正在与应用进行交互,可以在此实现与用户的交互功能。

ViewDispatchActivity.java

@Override
public void onUserInteraction() {
    Log.e("ViewDispatchActivity", "onUserInteraction");
    super.onUserInteraction();
}

Activity.java 也就是:

public void onUserInteraction() {
}

ViewGroup.superDispatchTouchEvent()

2、如果Window抽象类的实现类PhoneWindow的superDispatchTouchEvent()方法返回true,则当前方法也返回true。

继续看下PhoneWindow,可知调用的是DecorView的superDispatchTouchEvent()方法:

PhoneWindow.java

@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);
}

继续看下DecorView,可知调用的是ViewGroup的dispatchTouchEvent()方法: DecorView.java

public boolean superDispatchTouchEvent(MotionEvent event) {
    return super.dispatchTouchEvent(event);
}

继续看下ViewGroup: ViewGroup.java

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
 ......
 return handled;
}

由此,我们知道了Activity是如何将事件传递给ViewGroup的,并且知道了ViewGroup的dispatchTouchEvent()方法返回结果决定了Activity的dispatchTouchEvent()方法的返回结果。

Activity.onTouchEvent()

3、如果Window抽象类的实现类PhoneWindow的superDispatchTouchEvent()方法返回false,则调用onTouchEvent()方法。 ViewDispatchActivity.java

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.e("ViewDispatchActivity","onTouchEvent");
    return super.onTouchEvent(event);
}

也就是: Activity.java

public boolean onTouchEvent(MotionEvent event) {
    if (mWindow.shouldCloseOnTouch(this, event)) {
        finish();
        return true;
    }
    return false;
}

以上可知,如果Window的shouldCloseOnTouch()方法返回true,则结束当前Activity,并且返回true;否则返回false。

继续看下Window的shouldCloseOnTouch()方法: Window.java

public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
    final boolean isOutside =
            event.getAction() == MotionEvent.ACTION_UP && isOutOfBounds(context, event)
            || event.getAction() == MotionEvent.ACTION_OUTSIDE;
    if (mCloseOnTouchOutside && peekDecorView() != null && isOutside) {
        return true;
    }
    return false;
}

以上可知,如果触摸事件在边界外,将会结束当前Activity,并且返回true,否则返回false。

总结

81408eb131992f019f64996fd3491ad8.png

后续

ViewGroup和View对触摸事件的分发流程,笔者将在接下来的文章进行讲解,敬请关注。

欢迎关注Android技术堆栈,专注于Android技术学习的公众号,致力于提高Android开发者们的专业技能!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值