android面试 (基础篇 11)

本文详细解析了touch事件的传递过程,包括按下Down、移动Move、取消Cancel和离开触摸屏Up等基本事件。阐述了如何在Activity、View和ViewGroup中处理touch事件,探讨了dispatchTouchEvent、OnTouchListener和onTouchEvent的作用及常见问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9)touch事件的传递

    touch事件既是用手触摸屏幕所触发的事件。这些事件基本包括按下Down,移动Move

    取消Cancel和离开触摸屏Up四种事件。一个完整的Touch过程一般是由Down->(Move)

    ->Up/Cancel这四个事件做成,值得注意的是,一个完整的触摸事件必须由Down开始,

    再到Up/Cancel技术,中间的Move可有可无,当然touch事件不止这四个事件,但是这

    四个事件是最基本,开发中必须考虑到的。

    当用户开启应用触摸屏幕,系统服务就通过IPC通知应用的主线程Lopper,最终传递到我

    们应用中的Activity,View和ViewGroup中。

    一个touch事件要传递到View中,必须经过Activity向下分发,如果在ViewGroup在子View

    中找到可以处理这个事件的View,则向下传递下去,否则ViewGroup会尝试处理这个事件。

    (1)View的Touch逻辑

            分发:dispatchTouchEvent向接收Touch事件的子View(包括自己)派发事件,对于

            View而非ViewGroup来说,只会对自己分发

            处理:OnTouchListener在dispatchTouchEvent中被调用,是可选方法。onTouchEvent

            默认方法,在dispatchTouchEvent中被调用,如果设置了OnTouchListener,并且

            OnTouchListener消费了这个事件,返回true,则不会触发这个函数。

    (2)dispatchTouchEvent

            - 派发事件时首先停止嵌套滑动(5.0以后)

            - 如果View开启了安全检测(setFilterTouchesWhenObscured(true))并且当前View所在

              的Window被其他Window整改的话,则不会调用在处理Touch事件。

            - 如果当前View是Enabled,才会调用OnTouchListener

            - 不管Enable与否,只要OnTouchListener没有处理事件就会调用onTouchEvent()来处理事件

     (3)onTouchEvent

            - 不管View是否是Enabled,只要是clickable或者longclickable,就一定消费事件(返回true)

            - 如果View是UnEnabled,并且clickable或者longclickable,就只会消费事件不做其他操作

            - 如果View是Enabled,先看看TouchDelegate消费与否,如果不消费再给自己消费

            - 处理包括focus,press,click,longclick事件


    (4)常见的Touch事件处理问题解决

            - touch监听器没被调用到? 

              看View.dispatchTouchEvent(),ViewGroup.dispatchTouchEvent() 

              a)如果是View非使能,直接用setEnabled(true) 

              b)如果是事件被这个View的viewparent拦截了。可以修改这个viewparent的onInterceptTouchTouchEvent(),

                 或者在这个View中调用getParent().requestDisallowInterceptTouchEvent()

            - 双层滑动模块嵌套后发生滑动不了的现象? 

              看ViewGroup.dispatchTouchEvent() 如果是事件被这个View的viewparent拦截了。可以修改这个viewparent

              的onInterceptTouchTouchEvent(),或者在这个View中调用getParent().requestDisallowInterceptTouchEvent()

            - 设置了onClickListener后,点击View没有反应? 

              看View.onTouchEvent() 

             a)如果是View非使能,直接用setEnabled(true) 

             b)可能覆盖了onTouchEvent(),需要在覆盖的方法调用super.onTouchEvent()或者手动调用performClick()

            - 点击两下View才调用onClickListener的bug? 

              看View.onTouchEvent() 这个其实是安卓的设计,当某个View调用了setFocusableInTouchMode(true)后,

              第一次点击会引起这个View的focus,第二次点击才会调用onClickListener,只需要设置

              setFocusableInTouchMode(false)即可。问题解决


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值