Android View基础

前言

作为一个Android手机用户,最直观明显感受一个app的好坏的标准就是UI效果,一个好的UI体验是提升用户粘性先决条件。所以最为Android的开发者,学习自定义View是我们绕不开也躲不掉的。如何开发一个稳定、健壮的自定义View呢?这需要我们对自定义View流程及原理的理解程度的多少所决定。

View类简介

  • View类是Android中各种视图View的基类,如View 是ViewGroup的基类
  • View的表现为显示在屏幕上的各种视图
  • View的构造函数:共有4个构造函数

View构造函数

// 如果View是在Java代码里面new的,则调用第一个构造函数 
public TestView(Context context) {
   super(context);
}// 如果View是在.xml里声明的,则调用第二个构造函数 
// 自定义属性是从AtttrbuteSet参数传进来的
public TestView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

// 不会自动调用,一般是在第二个构造函数里面主动调用,如果view 有style属性时 
public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}// API 21 之后才使用
// 不会自动调用,一般是在第二个构造函数里面主动调用,如果view 有style属性时 
public TestView(Context context, AttributeSet attrs, int defStyleAttr
    , int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}复制代码

AttributeSet与自定义属性

系统自带的View可以在xml中配置属性,自定义View也同样可以在xml中配置属性,为了使自定义View的属性可以在xml中配置,需要以下4个步骤

  • 通过<declare-styleable>为自定义View添加属性
  • xml中为相应的属性声明属性值
  • 在运行时(一般在构造函数)获取属性值
  • 将获取到的属性值应用到View

View的绘制流程

如图所示,view的各个函数的功能及执行顺序


注意invalidate()函数能够让视图重新执行onDraw()而不需要重新测量布局, requestLayout()函数能够重新执行onMeasure()->onLayout()->onDraw() 绘制流程。所以在刷新视图的时候如果仅仅只改变了视图内容我们只需要调用invalidate() 或 postInvalidate(),减少没必要的cpu开销从而提升性能

View的分类

自定义View按布局能力区分,可以分为ViewViewGroup

  • 自定义View
    • 在没有现成的View,需要自己实现的时候,就使用自定义View,一般继承自View,SurfaceView或其他的View
    • 主要是实现 onMeasure + onDraw
  • 自定义ViewGroup
    • 自定义ViewGroup一般是利用现有的组件根据特定的布局方式来组成新的组件,大多继承自ViewGroup或各种Layout
    • 主要是实现onMeasure + onLayout

View视图结构

  1. PhoneWindow是Android系统中最基本的窗口系统,继承自Windows类,负责管理界面显示以及事件响应。它是Activity与View系统交互的接口
  2. DecorView是PhoneWindow中的起始点View,继承于View类,作为整个视图容器来使用。用于设置窗口属性。它本质上是一个FrameLayout
  3. ViewRoot在Activity启动时创建,负责管理、布局、渲染窗口UI等等


对于多View视图,结构是树形结构:如下


注意:无论是measure过程,layout过程还是draw过程,永远都是从View树的根节点开始测量或计算,一层层、一个分支一个分支的进行,最终计算整个View树的各个View,最终确定整个View树的相关属性

Android坐标系

自定义View除了上面必须掌握的知识点,还需要了解Android 坐标点。

Android的坐标系定义为:

  • 屏幕的左上角为坐标原点
  • 向右为X轴增大方向
  • 向下为Y轴增大方向


View位置描述:

View的位置由4个顶点决定,4个顶点的描述由4个值决定:

(请记住View的位置是相对父控件而言的)
  • Top:子View上边界距离父View上边界的距离
  • Left:子View左边界距离父View左边界的距离
  • right:子View右边界距离父View右边界的距离
  • Bottom:子View下边界距离父View下边界的距离

获取位置的方式:

View的位置通过getXXX()来获取

view.getTop(); // 获取top的位置
//下面同理
view.getLeft(); 
view.getRight();
view.getBottom();复制代码

于MotionEvent 的getXXX()和getRawXXX()的区别

// 触摸点相对于其所在组件坐标系的坐标
event.getX()
event.getY()
// 触摸点相对于屏幕默认坐标系的坐标
event.getRawX()
event.getRawY()
复制代码


分类:
阅读
标签: