文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android控件TextView的实现原理分析

2022-06-06 12:55

关注

  我们以窗口为单位,分析了WindowManagerService服务的实现。同时,在再前面一个系列的文章中,我们又分析了窗口的组成。简单来说,窗口是由一系列的视图按照一定的布局组织起来的。实际上,每一个视图都是一个控件,这些控制可以将自己的UI绘制在窗口的绘图表面上,同时还可以与用户进行交互,即获得用户的键盘或者触摸屏输入。在本文中,我们详细分析窗口控件的上述实现原理。

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

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

  从前面Android应用程序窗口(Activity)实现框架简要介绍和学习计划这个系列的文章可以知道,应用程序窗口,即Activity窗口,是由一个PhoneWindow对象,一个DecorView对象,以及一个ViewRoot对象来描述的。其中,PhoneWindow对象用来描述窗口对象,DecorView对象用来描述窗口的顶层视图,ViewRoot对象除了用来与WindowManagerService服务通信之外,还用来接收用户输入。窗口控件本身也是一个视图,即一个View对象,它们是以树形结构组织在一起形成整个窗口的UI的。为了简单起见,本文假设要分析的TextView控件是直接以窗口的顶层视图为父视图的,即以DecorView为父视图,如图1所示:

  图1 窗口结构示意图以及DecorView、TextView的类关系图

  图1显示的是一个包含了TextView控件的Activity窗口的结构示意图以及DecorView、TextView的简单类关系图,从中可以看出:

  1. 用户输入首先是由ViewRoot接收,然后再分发给TextView处理;

  2. DecorView是一个视图容器,因此,它是从ViewGroup继承下来,而ViewGroup本身又是从View继承下来的;

  3. TextView是一个简单视图,因此,它是直接继承了View。

  接下来,我们以图1所示的Activity窗口为例,来分析TextView控件的UI绘制框架及其获得键盘输入的过程。

  一. TextView控件的UI绘制框架

  从前面Android应用程序窗口(Activity)的测量(Measure)、布局(Layout)和绘制(Draw)过程分析一文可以知道,Activity窗口的UI绘制操作分为三步来走,分别是测量、布局和绘制。

  1. 测量

  为了能告诉父视图自己的所占据的空间的大小,所有控件都必须要重写父类View的成员函数onMeasure。

  TextView类的成员函数onMeasure的实现如下所示:

  [java] view plaincopyprint?

  public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {

  ......

  @Override

  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  int widthMode = MeasureSpec.getMode(widthMeasureSpec);

  int heightMode = MeasureSpec.getMode(heightMeasureSpec);

  int widthSize = MeasureSpec.getSize(widthMeasureSpec);

  int heightSize = MeasureSpec.getSize(heightMeasureSpec);

  int width;

  int height;

  //计算TextView控件的宽度和高度

  ......

  setMeasuredDimension(width, height);

  }

  ......

  }

  public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {

  ......

  @Override

  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  int widthMode = MeasureSpec.getMode(widthMeasureSpec);

  int heightMode = MeasureSpec.getMode(heightMeasureSpec);

  int widthSize = MeasureSpec.getSize(widthMeasureSpec);

  int heightSize = MeasureSpec.getSize(heightMeasureSpec);

  int width;

  int height;

  //计算TextView控件的宽度和高度

  ......

  setMeasuredDimension(width, height);

  }

  ......

  }

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


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯