Android 面试:事件分发8连问,androidrom移植

} else {

return dispatchGenericMotionEvent(event);

}

}

1.经过层层回调会调用到mView.dispatchPointerEvent

2.我们知道ViewRootImpl中的mView就是DecorView

现在事件已经传递到了DecorView,也就是我们界面的根布局

接下来是事件在Activity,Window,DecorView中的传递

2.4 事件在Activity,Window,DecorView中的传递

//DecorView.java

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

//cb其实就是对应的Activity/Dialog

final Window.Callback cb = mWindow.getCallback();

return cb != null && !mWindow.isDestroyed() && mFeatureId < 0

? cb.dispatchTouchEvent(ev) : 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);

}

//PhoneWindow.java

@Override

public boolean superDispatchTouchEvent(MotionEvent event) {

return mDecor.superDispatchTouchEvent(event);

}

//DecorView.java

public boolean superDispatchTouchEvent(MotionEvent event) {

return super.dispatchTouchEvent(event);

}

可以看到事件分发经过了:DecorView -> Activity -> PhoneWindow -> DecorView

看起来是一个很奇怪的事件流转,事件从DecorView出发,最后又回到了DecorView,为什么这样做呢?

2.4.1 为什么ViewRootImpl不直接把事件交给Activity

主要是为了解藕

ViewRootImpl并不知道有Activity这种东西存在!它只是持有了DecorView。所以,不能直接把触摸事件送到Activity.dispatchTouchEvent()

2.4.2 交给Acitivity后,为什么不直接交给DecorView开始分发事件呢?

因为Activity不知道有DecorView

但是,Activity持有PhoneWindow ,而PhoneWindow当然知道自己的窗口里有些什么了,所以能够把事件派发给DecorView

Android中,Activity并不知道自己的Window中有些什么,这样耦合性就很低了,Activity不需要知道Window中的具体内容

2.5 小结

经过上述过程,事件终于到了我们熟悉的ViewGroup.dispatchTouchEvent

流程图如下所示:

3.Touch事件到达页面后内部怎样分发


下面就是我们最常用也是最常见的事件分发部分了

3.1 ViewGroup是否拦截事件

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

final boolean intercepted;

//只有ActionDown或者mFirstTouchTarget为空时才会判断是否拦截

if (actionMasked == MotionEvent.ACTION_DOWN|| mFirstTouchTarget != null) {

final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;

if (!disallowIntercept) {

intercepted = onInterceptTouchEvent(ev);

}

}

if (!canceled && !intercepted) {

//事件传递给子view

if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {

//如果子View消耗了则给mFirstTouchTarget赋值

newTouchTarget = addTouchTarget(child, idBitsToAssign);

}

}

//mFirstTouchTarget不为空时会调用dispatchTransfor

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值