|
|
51CTO旗下网站
|
|
移动端
创建专栏

Android View 焦点寻址的来龙去脉 !!!

Android 系统的智能电视,最近两年基本上越来越火了,而在现在手机 App 开发中,都是使用触摸的模式进行操作,但是在开发智能电视 App 的时候,View 的焦点寻址,就是我们绕不过去的坎。

作者:张旸|2017-12-28 14:51

一、前言

Android 系统的智能电视,最近两年基本上越来越火了,而在现在手机 App 开发中,都是使用触摸的模式进行操作,但是在开发智能电视 App 的时候,View 的焦点寻址,就是我们绕不过去的坎。

那么,本文就 View 如何控制 Focus,来分析它背后的实现逻辑。

二、View 的焦点控制

在 Android 中,是有一套自己的焦点查找的算法,简单来说,就近原则,就是按方向就近查找下一个符合条件的 View。

如果我们有对一个 View 焦点控制的需求,需要对这个 View 强制指定它上下左右之后的下一个获取焦点的 View。可以通过 View 的属性来控制,只需要在对应方向上设定我们需要焦点转移的下一个 View 的 ID 即可。

  • android:nextFocusDown:按下的时候,焦点寻址的 ViewId。
  • android:nextFocusUp:按上的时候,焦点寻址的 ViewId。
  • android:nextFocusLeft:按左的时候,焦点寻址的 ViewId。
  • android:nextFocusRight:按右的时候,焦点寻址的 ViewId。
  • android:nextFocusForward:向前的时候,焦点寻址的 ViewId。

这些都是最基本的,不是本文的主题。那么如果没有设定这些属性,而 Android 对 View 的 就近原则 的焦点查找算法,到底是如何实现的呢?

三、View 的焦点寻址

Android 中,是如何做到对 View 焦点的控制呢?

我们就先从 View 的源码看起,看看它是如何找到“下一个”位置的 View的,在 View 中,查找下一个应该获取焦点的 View ,使用的方法是 focusSearch()。

它需要传递一个 direction 参数,这个 direction 就是指定获取什么方向上的下一个位置的焦点。

而 View 并不会处理焦点寻址的具体逻辑,而是将焦点的查找委托给 mParent 来实现,mParent 是一个接口,它的实现类是 ViewRootImpl。

ViewRootImlp.focusSearch() 最终又将焦点寻址的任务,交托给 FocusFinder 来处理。

findNextFocus()中可以看到,findNextUserSpecifiedFocus() 方法正是用于查找我们对 View 设定不同方向的下一个焦点的 ViewId ,它的优先级是最高的,如果没有找到,才会进行 findNextFocus() 通过算法来查找对应的 View。

为了证实这个说法,我们先看看 findNextUserSpecifiedFocus()的源码。

最终,又调回到 View.findUserSetNextFocus() 方法去寻找。

到这里也证实了我们的猜测,确实是通过 direction 来进行 View 的焦点寻址。

再回过头来看看 findNextFocus() 方法,如果通过 findNextUserSpecifiedFocus() 方法没有找到我们指定的 View,就会继续向下执行。这里声明的一个局部变量 focusables 就是用于存放符合算法的所有 View 。

接下来再看看如何向 focusables 这个 List 中,添加符合寻址要求的 View。在 findNextFocus() 中可以看到,它最终会调用 findNextFocusInAbsoluteDirection() 方法。

从 findNextFocusInAbsoluteDirection() 方法可以看出,就近原则就是在这里实现的,通过 View 的坐标点,计算出最符合要求的 View ,最终将找到的 View 返回过去。

到这里,基本就追踪到 View 对焦点寻址的完整逻辑。最后补一个方法调用的流程图。

四、总结

如果有对 View 焦点的控制,可以考虑通过设置 View 的属性,还可以通过重写 View.focusSearch() 方法,来定制 View 焦点的寻址规则。不过一般而言,不推荐重写 focusSearch() 方法,只使用属性控制也能满足我们的需求。

【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】

戳这里,看该作者更多好文

【编辑推荐】

  1. Android中以粗暴的方式替换全局字体
  2. 你真的了解Android密钥库吗?
  3. 外媒速递:谷歌Android Studio 3.0新特性概述
  4. Android 反编译利器,jadx的高级技巧
  5. 站在Android开发的角度,聊聊Airbnb的Lottie!!!
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

热门职位+更多