面试官为什么老问:Android事件分发机制?
通俗的说,就是当用户触摸屏幕时,这个事件传递的一个过程!
事件传递的原理又是什么呢?
这个事件传递原理就是责任链机制,OkHttp的核心原理也是用的责任链模式
简单的介绍下责任链模式:就是多个对象都有机会处理处理一个请求,并将这些对象连成一条链,沿着这条链处理传递事件,直到有对象处理传递事件为止。
举个栗子
产品狗——>CTO——>部门组长——>小开发仔
产品提了一个需求,CTO开始吩咐组长,组长就交给开发
这么一个链就行成了,需求,对象有了
过程应该会有这么几个情况
一个情况就是:开发看到这个需求觉得so Esay,分分钟搞定,反馈给组长,组长反馈给CTO然后这个需求就解决了!
第二个情况就是:开发看到这个需求懵逼了,卧槽做不了,反馈给组长,组长反馈给CTO,然后CTO就把这个需求给处理了.
第三个情况:CTO觉得可做,把这个需求吩咐给组长,组长分发下去给Pro,Pro解决不了,返回给组长,组件一看可以做,自己就把处理了,反馈给CTO
第四个情况:CTO觉得可做,把这个需求吩咐给组长,组长为了照顾小开发们,自己解决了,反馈给CTO
第五个情况:CTO看到这个需求,觉得这个需求很傻逼直接给拦截处理了.
事件分发是有哪些对象连成一条链呢?
ViewGroup:组件群
dispatchTouchEvent():事件分发方法
onInterceptTouchEvent ():事件拦截
onTouchEvent():事件处理
View:小组件
dispatchTouchEvent():事件分发方法
onTouchEvent():事件处理
用代码还原场景
CTO
public class CTOView extends LinearLayout{
public CTOView(Context context) {
super(context);
}
public CTOView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CTOView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("zouxj----->","CTOView dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d("zouxj----->","CTOView onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("zouxj----->","CTOView onTouchEvent");
return super.onTouchEvent(event);
}
}
组长
public class TeamLeaderView extends LinearLayout {
public TeamLeaderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public TeamLeaderView(Context context) {
super(context);
}
public TeamLeaderView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("zouxj----->","TeamLeaderView dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d("zouxj----->","TeamLeaderView onInterceptTouchEvent");
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("zouxj----->","TeamLeaderView onTouchEvent");
return super.onTouchEvent(event);
}
}
开发仔
public class ProGrammerView extends View {
public ProGrammerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ProGrammerView(Context context) {
super(context);
}
public ProGrammerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d("zouxj---->", "ProGrammerView dispatchTouchEvent");
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("zouxj---->", "ProGrammerView onTouchEvent ");
return super.onTouchEvent(event);
}
}
image.png
点击Pro比如一个需求
情况一:CTO得到一个需求,onInterceptTouchEvent()没有拦截,所以dispatchTouchEvent()分发给Leader,它也做了同样的事onInterceptTouchEvent()没有拦截,所以dispatchTouchEvent()分发给了Pro
image.png
情况二:Pro对这个需求做不了,把 onTouchEvent(MotionEvent event)=false
情况三:Pro对这个需求做不了,Leader把这个事情处理了onTouchEvent(MotionEvent event)=true,不需要CTO自己处理
image.png
情况四:组长接到需求不分发下去,onInterceptTouchEvent(MotionEvent ev)=false,这时没有Pro什么事了
image.png
情况五,CTO觉得这个需求不科学 onInterceptTouchEvent(MotionEvent ev)=true,不分发下去了,自己去和产品重新商量,所以没有后面的组长和开发什么事了
image.png
以上就是对于栗子的还原
总结:
以上给小白看到,高手忽略即可!
在传递流程和处理流程中,你都可以修改方法的返回值,来对流程做控制。
如下: 对于事件的拦截,我们主要重写就是OnInterceptTouchEvent和onTouchEvent方法。
1.事件的传递,返回结果为true,表示拦截,不再往下传递,为false,不拦截,继续往下传递。主要针对的就是OnInterceptTouchEvent方法。
2.事件的处理,返回结果为true,表示拦截,不再往上传递(即我处理的很完美,不需要你再来审核我!),返回结果为false(没有成功处理事件),继续向上传递。 针对就是onTouchEvent方法。
网友评论