自定义View -------- 浅析

View的坐标系

一.屏幕坐标系和数学坐标系的区别

由于移动设备一般定义屏幕左上角为坐标原点,向右为x轴增大方向,向下为y轴增大方向, 所以在手机屏幕上的坐标系与数学中常见的坐标系是稍微有点差别的,详情如下

自定义View -------- 浅析_第1张图片
image

实际屏幕上的默认坐标系如下:

自定义View -------- 浅析_第2张图片
image
注意:View的坐标系统是相对于父控件而言的.
  • getTop(); //获取子View左上角距父View顶部的距离
  • getLeft(); //获取子View左上角距父View左侧的距离
  • getBottom(); //获取子View右下角距父View顶部的距离
  • getRight(); //获取子View右下角距父View左侧的距离


    自定义View -------- 浅析_第3张图片
    image

三.MotionEvent中 get 和 getRaw 的区别

event.getX(); //触摸点相对于其所在组件坐标系的坐标
event.getY();
event.getRawX(); //触摸点相对于屏幕默认坐标系的坐标
event.getRawY();
自定义View -------- 浅析_第4张图片
image

onmeasure 宽度测量规格 高度测量规格

widthMeasureSpec HeightMeasureSpec

规格又分为      测量大小和测量模式

继承ViewGrop方法必须重写一个onlayout方法

颜色

一.简单介绍颜色
安卓支持的颜色模式:

颜色模式 备注
ARGB8888 四通道高精度(32位)
ARGB4444 四通道低精度(16位)
RGB565 屏幕默认模式(16位)
Alpha8 仅有透明通道(8位)
其中字母表示通道类型,数值表示该类型用多少位二进制来描述。如ARGB8888则表示有四个通道(ARGB),每个对应的通道均用8位来描述。
注意:我们常用的是ARGB8888和ARGB4444,而在所有的安卓设备屏幕上默认的模式都是RGB565,请留意这一点。
以ARGB8888为例介绍颜色定义:
类型 解释 0(0x00) 255(0xff)
A(Alpha) 透明度 透明 不透明
R(Red) 红色 无色 红色
G(Green) 绿色 无色 绿色
B(Blue) 蓝色 无色 蓝色

自定义View分类与流程

自定义View绘制流程函数调用链(简化版)

自定义View -------- 浅析_第5张图片
image
我们将自定义view分为四类
1.集成五大布局(已经帮我们写好了一些容器规则)
    组合控件
2.集成ViewGroup 流式布局
3.集成原有的控件(RecycleView,TextView,lecyvleView,image)
4.继承view  使用画笔画出来

测量View大小(onMeasure)

为什么要测量View大小?
View的大小不仅由自身所决定,同时也会受到父控件的影响,为了我们的控件能更好的适应各种情况,一般会自己进行测量。
测量View大小使用的是==onMeasure==函数,我们可以从onMeasure的两个参数中取出宽高的相关数据:
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthsize = MeasureSpec.getSize(widthMeasureSpec);      //取出宽度的确切数值
        int widthmode = MeasureSpec.getMode(widthMeasureSpec);      //取出宽度的测量模式
        
        int heightsize = MeasureSpec.getSize(heightMeasureSpec);    //取出高度的确切数值
        int heightmode = MeasureSpec.getMode(heightMeasureSpec);    //取出高度的测量模式
    }
从上面可以看出 onMeasure 函数中有 widthMeasureSpec 和 heightMeasureSpec 这两个 int 类型的参数, 毫无疑问他们是和宽高相关的, 但它们其实不是宽和高, 而是由宽、高和各自方向上对应的测量模式来合成的一个值:

测量模式一共有三种, 被定义在 Android 中的 View 类的一个内部类View.MeasureSpec中:

确定View大小(onSizeChanged)

这个函数在视图大小发生改变时调用。

在测量完View并使用setMeasuredDimension函数之后View的大小基本上已经确定了,那么为什么还要再次确定View的大小呢?

这是因为View的大小不仅由View本身控制,而且受父控件的影响,所以我们在确定View大小的时候最好使用系统提供的==onSizeChanged==回调函数。

onSizeChanged如下:

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }
可以看出,它又四个参数,分别为 宽度,高度,上一次宽度,上一次高度。
这个函数比较简单,我们只需关注 宽度(w), 高度(h) 即可,这两个参数就是View最终的大小。

=========

确定子View布局位置(onLayout)

确定布局的函数是onLayout,它用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。
在自定义ViewGroup中,onLayout一般是循环取出子View,然后经过计算得出各个子View位置的坐标值,然后用以下函数设置子View位置。
child.layout(l, t, r, b);
四个参数分别为:
名称 说明 对应的函数
l View左侧距父View左侧的距离 getLeft();
t View顶部距父View顶部的距离 getTop();
r View右侧距父View左侧的距离 getRight();
b View底部距父View顶部的距离 getBottom();

具体可以参考 坐标系 这篇文章。


绘制内容(onDraw)

onDraw是实际绘制的部分,也就是我们真正关心的部分,使用的是Canvas绘图。
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

关于Canvas绘图是本章节的重点,会分几篇文章进行详细讲解,敬请期待OwO。

======
事件分发机制

你可能感兴趣的:(自定义View -------- 浅析)