1.Android焦点移动requestFocus 源码分析一
Android焦点移动requestFocus 源码分析一
本文从源码角度深入分析了Android设备中焦点移动和点击触发机制。当用户点击上下左右按键时,UI会显示底部阴影,而点击Enter键则触发对应View的点击事件。这整个过程主要涉及到的方向按键处理、普通按键分发流程以及系统功能按键处理。视频模版源码
点击方向按键的事件首先由InputMethodManager$ImeInputEventSender接收,然后交由ViewRootImpl处理。ViewRootImpl通过一系列State的链式调用,最终在ViewGroup的requestFocus方法中被调用,最终调用View的requestFocus方法。值得注意的是,按键事件是从输入法(ImeInputEventSender是用于接收输入法按键事件的应用组件)传递的,而非ViewRootImpl直接处理。
普通按键的仿源码无忧分发流程中,ViewRootImpl的WindowInputEventReceiver可以接收到键盘输入事件,然后分发给View.dispatchKeyEvent,最后可能触发Activity的onKeyDown与onKeyUp方法。然而,系统会直接处理大部分功能按键(如亮度调节、音量键、媒体按键等),国外vba源码而不会将它们分发给View进行处理。
系统功能按键处理在InputMethodManager中定义,这部分会先将按键事件传递给输入法进行处理,然后将结果传给与输入法绑定的window。InputMethodManager中的mCallback实现类是ViewRootImpl$ImeInputStage,如果handled为true表示输入法已经处理过事件,否则会进入ViewRootImpl的店小赚源码finish或forward方法。
View的焦点移动主要通过View.requestFocus和requestFocusNoSearch方法实现。无论通过按键还是手动调用方法,流程都会最终指向requestFocusNoSearch,进一步处理焦点获取和释放逻辑。ViewGroup重写了handleFocusGainInternal方法来处理焦点获得的内部流程,首先清理当前ViewGroup的mFocused标记,然后调用super.handleFocusGainInternal方法。aes源码注释通过层层递归,整个View树会更新完成焦点状态,并通知OnFocusChangeListener监听方法,更新背景状态以突出焦点View。
descendantFocusability标记位在ViewGroup中起着决定性作用,它定义了ViewGroup对子View焦点的处理方式,有三种行为。当ViewGroup的一个子View获取焦点时,该ViewGroup本身并不会获得焦点,只有子View的mPrivateFlags标记位被赋值为PFLAG_FOCUSED时,才表明获取了焦点。isFocused与hasFocus不同,isFocused用于判断当前View是否具有焦点。
当需要查询当前获取到焦点的View时,可以使用findFocus方法。该方法在View类中定义,而在ViewGroup类中重写了它,实现逻辑简单,主要检查当前ViewGroup的mPrivateFlags标记位是否包含PFLAG_FOCUSED,若包含则返回当前View,否则返回null。
综上所述,本文从源码角度详细解析了Android设备中焦点移动和点击事件触发的实现机制,包括按键事件的处理流程、View的焦点获取与释放机制以及descendantFocusability标记位的作用。