View绘制01-Android渲染系统中的View

Android渲染系统中的View

对于初级开发者而言,在面试中,经常会和面试官聊到Android四大组件,聊到Activity,其中回答最纯熟的一句话就是:

Activity的作用是应用与用户之间交互的重要组件

那么Activity之交互功能又是怎么实现的呢?答案不言而喻-View

我们在Activity onCreate的时候调用setContentView方法为Activity设置布局,实际上就相当于对用户开放了多个交互接口,用户可以通过布局中一个一个的View进行自己想要的操作,我们也可以通过View来向用户展示结果信息,那么View在Android渲染系统中长啥样呢?

首先我们打开系统的开发者选项( 通过多次点击 系统设置 > 关于本机中的版本号开启),找到显示布局边界选项并打开(如下图所示),
在这里插入图片描述
打开后,我们可以看到界面上多了很多不同颜色的线框以及矩形蒙版,这些线框圈中的部分就代表着一个View或者ViewGroup,阴影部分显示的是距父布局的Margin或者Padding(如下图所示)。
在这里插入图片描述

从上面两张图我们可以看到Android渲染系统中以点阵为基本元素,用一个矩形区域来渲染View,同时在这个矩形区域内响应用户交互,从Android渲染系统角度来看,View就是点阵里面的一块矩形区域

Android源码中的View

不论是Java还是Kotlin,其语言特性就是面向对象,那么View作为Android体系中的一部分,毫无疑问,它是一个对象,那么这个对象有什么特性呢?我们来看下官方源码中的说明:

This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The
{@link android.view.ViewGroup} subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.

上面这句话主要阐述了如下几个要点:

  1. View的形状以及作用:View是屏幕上用于进行数据渲染展示和处理用户事件的矩形区域,这一点我们通过第一部分渲染系统已充分认识到。
  2. View的顶级父类特性:View是所有组件及Layout的直接或间接父类,这一点我们可以通过绘制各组件类继承关系认识到(如下图)。
    在这里插入图片描述看了源码中关于View的定义,同学们是否对View认识更加清晰了呢?

同学们都知道,Android中有两种布局管理方式,通过Java代码或者xml布局文件(两者经常组合使用,这里我们不单独列出),我们来看下一个典型的java代码控制布局的例子,代码如下图:
在这里插入图片描述
这里我们通过new关键词生成了TextView对象,并将其设置在Activity的布局上,使用xml布局方式同样能打开上图右侧运行效果,但是TextView对象又是什么时候生成的呢?这就涉及到AndroidView的管理-View树,了解View树的创建过程,有利于我们更好的理解Android中的View管理机制,后续文章或小册中我们将做更详细的阐述。

Android系统坐标系及View坐标系

View作为屏幕上一块用于用户交互和数据展示的矩形区域,那么这块矩形区域的渲染分工是怎么的呢?又是怎么确定这块矩形区域绘制在哪里呢?联想数学中,我们在绘制图形之前,首先会确立什么?没错,坐标系。在Android中也有坐标系的概念,与View相关的主要有Android屏幕坐标系和View坐标系,Android屏幕坐标系用于系统确认该在什么位置绘制多大的矩形区域以展示ViewView坐标系用于View内部进行自我绘制时确认绘制方向和大小。

Android屏幕坐标系如下图所示,以屏幕左上角为坐标原点,向右为X正方向,向下为Y正方向。
在这里插入图片描述
View坐标系与Android屏幕坐标系类似,如下图所示,只不过其坐标原点位于View所在矩形区域的左上角,向右为X正向,向下为Y正向。
在这里插入图片描述
从上图中我们可以看出,所有的ViewLayout内部的坐标系均是View坐标系,同时也可以看到getTop()getLeft()getRight()以及getBottom()这四个函数具体所对应的距离含义。当我们在View内部进行测量绘制时,经常需要用到这四个函数,通过这四个函数我们可以手动计算该View在界面上矩形区域的宽度和高度(注意这里描述的是界面上矩形区域,即View的用户可见部分,在View内部是没有边界可言的,理论上讲,一个View的内部可以无限绘制)。

可能有同学要问了,你讲了View坐标系,但是我需要知道View在屏幕坐标系中的位置怎么搞呢?也很简单,我们可以通过ViewgetBoundsOnScreen(Rect outRect)获取View在屏幕上的矩形区域,那么View在屏幕坐标系中的位置就显而易见了。

也许有同学见过重写onTouchListener,自己拦截事件的操作,这种情况下我们就需要获取当前触摸点的位置以用于判断是否进行业务逻辑处理,具体说明如下图:
在这里插入图片描述
从上图我们可以看出getRawX()getRawY()是触摸点距离屏幕坐标系坐标原点的距离,getX()getY()是触摸点距离View坐标系坐标原点的距离,通常情况下,如果是View整体的触屏事件处理,例如拖动View,点击View,我们选用getRawX()getRawY(),如果是View内部的事件处理,例如进行View***内容***的滚动,我们选用getX()getY()

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页