美文网首页
举个栗子说下Android事件分发

举个栗子说下Android事件分发

作者: 大佬的上半生 | 来源:发表于2019-11-22 18:39 被阅读0次

面试官为什么老问: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

image.png
情况三: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方法。

CTO——onInterceptTouchEvent()&dispatchTouchEvent()—>Leader
—onInterceptTouchEvent()&dispatchTouchEvent()——>Pro
—onTouchEvent()——>Leader——onTouchEvent()——>CTO

相关文章

网友评论

      本文标题:举个栗子说下Android事件分发

      本文链接:https://www.haomeiwen.com/subject/koafwctx.html