Android TextView功能分析

  次阅读 来源:互联网(转载协议) 2015-11-25 22:13 我要评论(0)

由于Android系统提供的控件比较多,因此我们只能挑一个比较有代表的控件进行分析。这个比较有代表性的控件便是TextView,其它的一些基础控件,例如Button、EditText和CheckBox等,都是直接或者间接地以它为父类的。每一个控件的实现都是相当复杂的,不过基本上都是一些细节问题,而且不同的控件有不同的实现细节,因此,本文并不打算详细地分析TextView的具体实现,而是从所有控件为了实现自己的功能而需要的东西出发,去分析TextView的实现框架。

那么,控件为了实现自己的功能而需要的东西是什么呢?有两个材料是必不可少的。第一个材料是画布,第二个材料是用户输入。有画布才能绘制UI,而有用户输入才能与用户进行交互。因此,接下来我们主要分析TextView的绘制流程,以及它获得用户输入的过程。用户输入主要包括键盘输入以及触摸屏输入,本文主要关注的是键盘输入。触摸屏输入与键盘输入的获取过程是类似的,读者如果有兴趣的话,可以参照本文的内容来自己研究一下。

这个函数定义在文件frameworks/base/core/java/android/view/ViewRoot.java中。

参数event描述的是窗口接收到的键盘事件,另外一个参数sendDone表示该键盘事件处理完成后,是否需要向系统的输入管理器发送一个通知。

ViewRoot类的成员变量mView描述的是窗口的顶层视图,即它指向的是一个DecorView对象,ViewRoot类的成员函数deliverKeyEvent首先是调用它的成员函数dispatchKeyEventPreIme来让它优先于输入法处理参数event所描述的键盘事件。如果这个DecorView对象的成员函数dispatchKeyEventPreIme的返回值handled等于true,那么就说明参数event所描述的键盘事件已经处理完毕,即ViewRoot类的成员函数deliverKeyEvent不用往下执行了。在这种情况下,如果参数sendDone的值等于true,那么ViewRoot类的成员函数deliverKeyEvent在返回之前,还会调用成员函数finishInputEvent来通知系统的输入管理器,当前激活的窗口已经处理完成刚刚发生的键盘事件了。在接下来的Step 2到Step 4中,我们再详细分析键盘事件优先于输入法分发给窗口处理的过程。

假设窗口不在输入法前面拦截参数event所描述的键盘事件,接下来ViewRoot类的成员函数deliverKeyEvent就会将该键盘事件分发给输入法处理,这个分发过程如下所示:

1. 调用InputMethodManager类的静态成员函数peekInstance获得一个类型为InputMethodManager输入法管理器imm;

2. 调用ViewRoot类的成员函数enqueuePendingEvent将参数event所描述的键盘事件缓存起来,等到输入法处理完成该键盘事件之后,再继续对它进行处理;

3. 调用第1步获得的输入法管理器imm的成员函数dispatchKeyEvent来将参数event所描述的键盘事件分发给输入法处理。

这里有两个地方是需要注意的。第一个地方是只有当前窗口正在显示输入法的情况下,ViewRoot类的成员函数deliverKeyEvent才会将参数event所描述的键盘事件分发给输入法处理,这是通过检查ViewRoot类的成员变量mLastWasImTarget的值是否等于true来确定的。第二个地方是在将参数event所描述的键盘事件分发给输入法处理时,ViewRoot类的成员函数deliverKeyEvent会同时传递一个类型为InputMethodCallback的回调接口给输入法,以便输入法处理完成参数event所描述的键盘事件之后,可以调用这个回调接口的成员函数finishedEvent来向窗口发送一个键盘事件处理完成通知。这个类型为InputMethodCallback的回调接口就保存在ViewRoot类的成员变量mInputMethodCallback中,当它的成员函数finishedEvent被调用的时候,它就会调用ViewRoot类的成员函数deliverKeyEventToViewHierarchy来继续将参数event所描述的键盘事件分发给窗口处理。

如果窗口当前不需要与输入法交互,即ViewRoot类的成员变量mLastWasImTarget的值等于false,那么ViewRoot类的成员函数deliverKeyEvent就会直接调用成员函数deliverKeyEventToViewHierarchy来将参数event所描述的键盘事件分发给窗口处理。

接下来,我们就先析窗口在输入法之前处理键盘输入的过程,接着再分析窗口在输入法之后处理键盘输入的过程。

从前面的分析可以知道,ViewRoot类的成员函数deliverKeyEvent是通过调用DecorView类的成员函数dispatchKeyEventPreIme来将获得的键盘输入优先于输入法分发给窗口处理的。DecorView类的成员函数dispatchKeyEventPreIme是从父类ViewGroup继承下来的,因此,接下来我们就继续分析ViewGroup类的成员函数dispatchKeyEventPreIme的实现。

Step 2. ViewGroup.dispatchKeyEventPreIme

[java]

public abstract class ViewGroup extends View implements ViewParent, ViewManager {

......

// The view contained within this ViewGroup that has or contains focus.

private View mFocused;

......

@Override

public boolean dispatchKeyEventPreIme(KeyEvent event) {

本站部分文章来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • Oculus公布原型机,大幅度提升可视角,能实现140°的视场水平

    Oculus公布原型机,大幅度提升可视角,能实现140°的视场水平

  • Michael I. Jordan带你解读百万奖金ATEC蚂蚁人工智能大赛

    Michael I. Jordan带你解读百万奖金ATEC蚂蚁人工智能大赛

  • 2018深圳国际人工智能展览会 2018 shenzhen International Artif

    2018深圳国际人工智能展览会 2018 shenzhen International Artif

  • teamLab创始人猪子寿之: 抛去衣食住行,我还剩下什么?

    teamLab创始人猪子寿之: 抛去衣食住行,我还剩下什么?

网友点评网友点评
阅读推荐阅读推荐

据外媒报道,STEER打造了首款完全自动驾驶停车技术,旨在使常规车辆转变为无人驾驶车辆。STEER的首款技术应用是4级自动驾驶及网络安全停车...

近日,美国软性机器抓手制造商 Soft Robotics 宣布,获得 2000 万美元的融资,本轮投资者包括 Scale Venture Partners,Calibrate Ventures...

据外媒报道,加州车管局发布了《2017自动驾驶脱离报告(California Autonomous Vehicle Disengagement Reports)》,其中谈及了脱离的具体...

用人机语音交互,来解决智能家居适老的问题;通过家庭门禁与安防套件、空气净化套件、可燃气体与有害气体监控套件等相互联动,在不同生活情...