Android事件分发源码剖析(一)之事件处理

Android事件分发源码剖析(一)之事件处理,第1张

概述主要写三个方面:1,事件分发分发的是什么事件(ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL(事件被上层拦截的时候触发))2,事件是怎么处理(通过对onTouch,onclick之间的关系解析)举一个案例,一个按钮同时监听onTouch,onclick,在onTouch()返回true,这时发现onclick没有被触发。通过这个现

主要写三个方面:

1,事件分发分发的是什么事件(ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL(事件被上层拦截的时候触发))

2,事件是怎么处理(通过对ontouch,onclick之间的关系解析)

举一个案例,一个按钮同时监听ontouch,onclick,在ontouch()返回true,这时发现onclick没有被触发。通过这个现象我看了下源码中的事件处理流程,可以在源码中找到以下的代码段。

    public boolean dispatchtouchEvent(MotionEvent event) {        // If the event should be handled by accessibility focus first.        if (event.isTargetAccessibilityFocus()) {            // We don't have focus or no virtual descendant has it, do not handle the event.            if (!isAccessibilityFocusedVIEwOrHost()) {                return false;            }            // We have focus and got the event, then use normal event dispatch.            event.setTargetAccessibilityFocus(false);        }        boolean result = false;        if (minputEventConsistencyVerifIEr != null) {            minputEventConsistencyVerifIEr.ontouchEvent(event, 0);        }        final int actionMasked = event.getActionMasked();        if (actionMasked == MotionEvent.ACTION_DOWN) {            // Defensive cleanup for new gesture            stopnestedScroll();        }        if (onFiltertouchEventForSecurity(event)) {            if ((mVIEwFlags & ENABLED_MASK) == ENABLED && handleScrollbarDragging(event)) {                result = true;            }            //noinspection SimplifiableIfStatement            ListenerInfo li = mListenerInfo;            if (li != null && li.mOntouchListener != null                    && (mVIEwFlags & ENABLED_MASK) == ENABLED                    && li.mOntouchListener.ontouch(this, event)) {                result = true;            }            if (!result && ontouchEvent(event)) {                result = true;            }        }        if (!result && minputEventConsistencyVerifIEr != null) {            minputEventConsistencyVerifIEr.onUnhandledEvent(event, 0);        }        // Clean up after nested scrolls if this is the end of a gesture;        // also cancel it if we trIEd an ACTION_DOWN but we dIDn't want the rest        // of the gesture.        if (actionMasked == MotionEvent.ACTION_UP ||                actionMasked == MotionEvent.ACTION_CANCEL ||                (actionMasked == MotionEvent.ACTION_DOWN && !result)) {            stopnestedScroll();        }        return result;    }

这个现象造成的原因就在上面,我把主要的语句摘录出来

            ListenerInfo li = mListenerInfo;            if (li != null && li.mOntouchListener != null                    && (mVIEwFlags & ENABLED_MASK) == ENABLED                    && li.mOntouchListener.ontouch(this, event)) {                result = true;            }            if (!result && ontouchEvent(event)) {                result = true;            }

可以看到当ontouch()返回true时,result会被赋值为true,而按钮的的onclick()其实是在ontouchEvent()执行的,所以不会执行到,这就是onclick()没有执行的原因了。(如果大家想验证下我们可以看看ontouchEvent()这个函数的实现。在case MotionEvent.ACTION_UP:可以找到performClick();这个函数,我们再次进入这个函数就可以看到我们的我们的li.mOnClickListener.onClick(this);)

也就是说我们事件具体的处理其实主要在VIEw的dispatchtouchEvent()和VIEw的ontouchEvent().这个时候如果我们要进入onclick()那么我们就把ontouch()返回false就可以啦。而如果我们想让ontouch()返回true,还想触发onclick(),那么我们可以在需要的动作中手动调用v.performClick();

3,分析源码,了解事件冲突的原因以及解决

 

总结

以上是内存溢出为你收集整理的Android事件分发源码剖析(一)之事件处理全部内容,希望文章能够帮你解决Android事件分发源码剖析(一)之事件处理所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1053270.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存