Android中最详细的焦点问题,从概念出发带你一点点分享(1)

文章最早发布于我的微信公众号 Android_De_Home 中,欢迎大家扫描下面二维码关注微信公众获取更多知识内容。
本文为sydMobile原创文章,可以随意转载,但请务必注明出处!

今天写的这篇博客主要是针对在Android中的焦点问题,网上有很多关于焦点博客文章,但是大多数都是不全的,要么就是直接分析源码,要么就是直接讲遇到什么问题怎么解决,总之不够全面。往往导致我们看完一篇博客后只是会了怎么解决那个问题,对什么是焦点还是说不出来,遇到问题还是解决不了。这也是我写这篇博客的主要原因。这篇博客从最简单的概念说起,然后一点点分享源码,让你可以对焦点不再模棱两可。

焦点概念

焦点在Android中也就是Focus,称为Focus机制。以后我们看到Focus就是指的焦点!那么什么是焦点机制呢?或者什么是焦点呢?
概念:所谓焦点就和我们生活中一样,比如你的同学聚会中,谁是焦点啊。其实意思差不多,焦点就是最受关注的哪一个,人们都围绕着它。再来回到我们Android开发中,比如一个页面有3个EditText,那么当你键盘输入内容的时候,这个时候会在哪一个EditText里面显示内容呢?这个时候就是谁获得了焦点就在那个EditText中显示内容。(注意:有很多人把焦点和点击混了,以为我点击了某个控件,这个控件就获取焦点了,这个是不一定的,不能这么认为!后面会有说明)

说白了就是你手机当前屏幕上的焦点在那个控件上,体现就是当前控件获取了焦点,对于EditText来说,体现就是键盘输入的内容,会输入到这个EditText上面。如果这个EditText没有获取焦点的话,键盘输入的内容是不会在EditText内显示的。

获取焦点的两种模式

触摸模式(TouchMode)与普通模式

用代码的体现就是:如果请求有触摸获取焦点的能力,在xml中的配置是 android:focusableInTouchMode="true"
请求有普通获取焦点的能力(可以理解为通过物理键盘),在xml中的配置是android:focusable="true"
具体的来说说这两种模式:

  • focusable

出现这种模式主要是因为Android系统不仅仅是针对手机的,有可能在电视、手表等等的非触摸输入设备上。在手机上其实普通模式很少用了,现在的手机基本都是触摸屏并且没有物理上下键的,这种模式是用在TV等一些有物理键的产品上面的。比如非触摸屏手机或者TV,如果设置为true,则键盘上下左右选中,焦点会随之移动。比如有物理上下键,你按一个向下键,屏幕上的内容就会对应选中一个向下的控件,如果这个控件有focusable能力的话这个时候这个控件就是获得了焦点。

  • focusableInTouchMode

在Android开发中对于现在的手机来说,都是触摸模式(TocuMode),就是当你触摸一个控件的时候,这个控件会获取焦点。注意:有些控件是默认不具有触摸获取焦点的功能的(Button、TextView、LinearLayout等等这些控件是默认没有触摸获取焦点功能的,为什么会有这种问题呢?原因是这些控件有时候可能会想要先响应点击事件,如果触摸获取焦点功能打开后,当你点一下,默认是不会调用点击事件的,这个时候会先让这个控件获取焦点)EditText是默认有触摸获取焦点功能的,并将第一抢先获取焦点。这就解释了为什么当一个页面有EditText的时候,我们进入的时候默认有光标,键盘弹出,这就是焦点在这EditText上面。
就像上面说的那些控件(Button、TextView等等这些默认没有触摸获取焦点功能的控件),当你点击它的时候,它也不会获取焦点也就是调用 isFocused()方法的时候返回的也是false,这个时候默认的是触发到它的点击事件。如果你配置了focusableInTouchMode的话这个时候这些控件才会获取焦点,而这个时候是不会触发点击事件的,触发的是 OnFocusChangeListener。这个时候获取了焦点,当你在点击的时候才会触发点击事件。

总结:这两个属性都是表示是否可以获取焦点,focusableInTouchMode是针对触屏的。 android:focusable是针对有物理键下操作的。我们在Android开发中主要是用focusableInTouchMode。

分析一下为什么出现EditText自动获取焦点的问题

我们都知道如果在布局中有EdiText的话,EditText会默认获得焦点,弹出键盘。解决方法网上也很多了,就是在EditText的父布局中添加 focusableInTouchMode = true 。网上大多数会添加focusable = true。我们通过上面的内容可以知道,对于手机来说,只需要添加 focusableInTouchMode = true 就可以了。
EditText自动获取焦点主要是因为当我们没有给EditText的父布局设置focusableInTouchMode的时候,它的父布局是默认没有这个能力的,所以焦点就会直接被EditText争夺去。如果我们设置了focusableInTouchMode的话,这样EditText的父布局就会有这个能力了,这样只有我们触摸的时候触发相应的事件,通过Android中的事件传递机制进行传递了。

那么问题来了Android中的事件传递机制是什么样的呢?请看下篇博客内容!

欢迎大家关注我的微信公众号,和我交流分享

推荐阅读更多精彩内容