Android事件处理(二)——View的dispatchTouchEvent 函数源码详解

作者: 林子木
博客地址:http://blog.csdn.NET/wolinxuebin


文章意图:

主要是想一自己阅读代码后的一些小收获分享给大家。让大家更加深入的了解Android的事件分发这块的内容。

文章主要内容:

本文将在第一章通过自己的语言,简单介绍View的dispatchTouchEvent,并将其中的一些关键点直接提炼出来,方便那些不想阅读源代码的同学把握住其中的关键点。

在第二章将放上源码,其中包含了我阅读过程中的10处注释。


第一章、View的dispatchTouchEvent关键点提炼

相对与Android事件处理(一)——ViewGroup的dispatchTouchEvent 函数源码详解,View的dispatchTouchEvent简单很多,主要就两点:

1、将事件派发给我们使用setOnTouchListener设置的OnTouchListener的 onTouch 处理;
2、如果1没有处理该事件(也就是没有返回true),那么就将事件派发给View本身的 onTouchEvent 函数处理;
简单的说,就是优先派发给我们设置的Listener,在给view自身的。

第二章、View的dispatchTouchEvent源码及分析

具体的源码及相应的注释如下:
    public boolean dispatchTouchEvent(MotionEvent event) {
        // If the event should be handled by accessibility focus first.
        //[lxb #1] 辅助功能,暂时可以不用理会
        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;
        //[lxb #2] 调试使用的,不需要理会
        if (mInputEventConsistencyVerifier != null) {
            mInputEventConsistencyVerifier.onTouchEvent(event, 0);
        }

        final int actionMasked = event.getActionMasked();
        if (actionMasked == MotionEvent.ACTION_DOWN) {
            // Defensive cleanup for new gesture
            //[lxb #3] Android的NestedScrolling机制,初学者查学习事件分发源码可以先滤过这部分
            //[lxb #3] 可以查看http://blog.csdn.net/lmj623565791/article/details/52204039 做一个初步的了解
            //[lxb #3] https://segmentfault.com/a/1190000002873657
            stopNestedScroll();
        }

        //[lxb #4] 如果窗口标记了FILTER_TOUCHES_WHEN_OBSCURED这个,
        //[lxb #4] 将不会进行下发;可以避免一个窗口盖在当前的窗口上,伪造事件下发
        if (onFilterTouchEventForSecurity(event)) {
            //noinspection SimplifiableIfStatement
            //[lxb #5] ListenerInfo 是一个listener集合, 包括onTouchListener、onClickListener等
            //[lxb #5] 我们调用setOnTouchListener 则是将listener 加入到 li.mOnTouchListener
            ListenerInfo li = mListenerInfo;

            //[lxb #6] 如果在View的情况下ENABLED,并且我们设置了OnTouchListener,事件将优先派发给我们设置的listener处理
            //[lxb #6] 如果OnTouchListener.onTouch消耗了该事件,那么将不会传递下去了
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            //[lxb #7] 将事件交给自身的onTouchEvent处理
            if (!result && onTouchEvent(event)) {
                result = true;
            }
        }

        //[lxb #8] 调试使用的,不需要理会
        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)) {
        	//[lxb #9] 可以查看 [lxb #3]
            stopNestedScroll();
        }
        //[lxb #10] 将事件处理的结果反馈给父类,也就是自身是否要消耗改事件,如果在down的情况下
        //[lxb #10] 如果在Action_Down的情况下,返回了true就是告诉父类,我将需要接受接下来的事件
        //[lxb #10] 如果在之后的事件动作如ACTION_MOVE返回了false,事件依旧会派发下拉
        return result;
    }




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值