Jack Frost

Android–焦点问题以及讨论事件传递机制问题(结合部分相关源码)

还是之前的项目中的一些东西,继续抽出来给大家。

文章结构:(1)展现焦点问题(以及一些体验交互的状态);(2)分析焦点问题,详解两个属性;(3)结合部分相关源码讨论事件传递机制;


一、展现焦点问题:

(1)如果对我下面给的demo不加一些属性处理,效果如下:

这里写图片描述

也就是看不到上面的轮播图,这样的话,就是recyclerview抢占了activity的焦点咯。

那么demo中,我们怎么解决的呢???

为什么这样做呢???

我何用做是为了给轮播图控件施加焦点嘛,我就在轮播图的父控件设定了android:focusableInTouchMode=true,也就拦截了轮播图默认行为让父控件得到高亮得到焦点,当然也抢夺了recyclerview想要的焦点。


(2)另外,大家在编写自己的登录页面时也经常遇到焦点问题吧??是什么导致的呢?是EditText!!它自动抢夺焦点的!!

EditText这种即使在TouchMode下,依然需要获取焦点的控件

怎么解决呢?

解决:在EditText的父级控件中找一个,设置成

这样,就把EditText默认的行为截断了!!不让它自动夺取焦点。

(3)讲述另外一些体验交互状态

Select

这里写图片描述

Focusable in Touch Mode

也就是我们上面的edittext,点击去获取焦点。

Focus

就是焦点模式咯。


二、分析焦点问题,详解两个属性:

focusableInTouchMode跟focusable有什么区别?

1.要理解这个属性,首先你得知道,Android不是只面向手机的,它还有可能被安装在电视等非触摸输入设备上.即使是在手机上,目前很多手机也都支持键盘输入了。

2.focusable这种属性,更多的是为了解决非触摸输入的,因为你用遥控器或键盘点击控件,就必然要涉及到焦点的问题,只有可以获得焦点的控件才能响应键盘或者遥控器或者轨迹球的确定事件.

3.focusableInTouchMode.这个属性的意思一如字面所述,就是在进入触摸输入模式后,该控件是否还有获得焦点的能力.

什么意思呢??再通俗点,

对于一个拥有触摸屏功能的设备而言, 一旦用户用手点击屏幕, 设备会立刻进入touch mode。这时候被点击的控件只有设置android:focusableInTouchMode为true的时候才会获得focus,比如EditText控件。其他可以触摸的控件比如Button。

然后其android:focusableInTouchMode默认为false, 当被点击的时候不会获取焦点,它们只是简单地执行onClick事件而已。

所以以上两个属性就针对这几种的touch情况啦。交互体验是十分地不同的!!!

所以我们大致看下这份源码的接口声明,我们就可以清晰认知focus跟touch是极大的不同。


三、讨论事件传递机制

焦点问题也是涉及到事件机制的,所以我们就顺便进一步地去讨论这个android事件机制咯。

关于事件的传递,我们主要是关注几个问题:(1)事件怎么传递?它的传递流程是怎样?(2)事件是怎么消费的??(3)自定义view也事件冲突时,我们怎么处理?(4)源码是怎么定义这个事件机制的??

(1)事件怎么传递?它的传递流程是怎样?

首先由Activity分发,分发给根View,也就是DecorView(DecorView为整个Window界面的最顶层View)。

然后由根View分发到子的ViewGroup,再由各个ViewGroup分发给子View

这里写图片描述

好了看下源码:

我们来仔细讨论ViewGroup事件的传递机制:

这里写图片描述

虽然那个图真的很棒,但是讲得不够清晰呢,下面我将它具体讲述。

(1)当我们点击viewC时,就会触发事件,然后事件传递给viewgroupA,viewgroupA它首先会执行dispatchTouchEvent来调用onInterceptTouchEvent判断本group是否可以处理,return ture则交由onTouchEvent处理事件,return false则使用dispatchTouchEvent往下传递事件。

(2)往下传递过来的事件由viewgroupB的onInterceptTouchEvent拦截,问自己能否处理该事件,能则处理,不能则往下继续传递。同理viewC的这一步流程。

(3)当传递到最终的viewC的时候,如果不能够处理该触发事件,是会重新回传给父控件的!!!!


(2)事件是怎么消费的??

就是dispatchTouchEvent判断自己能处理后就调用自己的onTouchEvent进行处理。

(3)自定义view时,我们怎么处理?

点这里看例子。感谢那位博主的精妙例子。

(4)源码是怎么定义这个事件机制的??

事件即MotionEvent:

(1)MotionEvent.ACTION_DOWN 按下View,是所有事件的开始

(2)MotionEvent.ACTION_MOVE 滑动事件

(3)MotionEvent.ACTION_UP 与down对应,表示抬起

dispatchTransformedTouchEvent源码:这个是把事件交给子view去处理的方法


参考博客:

生命壹号

郭朝


源码下载:Android-多列表的项目Rxjava+Rtrofit+Recyclerview+Glide+Adapter封装

好了,Android–焦点问题以及讨论事件传递机制问题讲完了。本博客是这个系列的第四篇,讨论的是我在项目中遇到的一些细节坑,以及它们的相关机制。另外,这个系列还有一些我在外包项目过程中做的优化,以及一些发布签名等等技巧,我会尽快出完给大家,分享经验给大家。欢迎在下面指出错误,共同学习!!你的点赞是对我最好的支持!!

更多内容,可以访问JackFrost的博客

码字很辛苦,转载请注明来自JackFrost《Android–焦点问题以及讨论事件传递机制问题(结合部分相关源码)》

8 responses to “Android–焦点问题以及讨论事件传递机制问题(结合部分相关源码)”

  1. A big thank you for your blog.Really looking forward to read more. Keep writing.

  2. Fantastic article.Much thanks again. Awesome.

  3. motoapk hihi says:

    Thank you ever so for you post.Really looking forward to read more. Will read on…

  4. suba buba says:

    rOMNav It as not that I want to copy your web site, but I really like the layout. Could you let me know which design are you using? Or was it tailor made?

  5. Im obliged for the article post.Much thanks again.

  6. pron best says:

    tguv6C Pretty! This was an incredibly wonderful article. Thanks for supplying this info.|

Leave a Reply

Your email address will not be published. Required fields are marked *