android以view建坐标系,Android自定义View三(坐标系与View的绘制流程)

涉及知识

绘制过程涉及到主要方法

类别

API

描述

布局

onMeasure

测量View与Child View的大小

onLayout

确定Child View的位置

onSizeChanged

确定View的大小

绘制

onDraw

实际绘制View的内容

事件处理

onTouchEvent

处理屏幕触摸事件

重绘

invalidate

调用onDraw方法,重绘View中变化的部分

Canvas涉及到主要方法

类别

API

描述

绘制图形

drawPoint、drawPoints、drawLine、drawLines、drawRect、drawRoundRect、drawOval、drawCircle、drawArc

依次为绘制点、直线、矩形、圆角矩形、椭圆、圆、散形

绘制文本

drawText、drawPosText、drawTextOnPath

依次为绘制文字、指定每个字符位置绘制文字、根据路径绘制文字

画布变换

translate、scale、rotate、skew

依次为平移、缩放、旋转、倾斜(错切)

画布裁剪

clipPath、clipRect、clipRegion

依次为按路径、按矩形、按区域或对画布进行裁剪

Paint涉及到主要方法

类别

API

描述

颜色

setColor、setARGB、setAlpha

依次为设置画笔颜色、透明度

类型

setStyle

填充(FILL),描边(STROKE),填充加描边(FLIL_STROKE)

抗锯齿

setAntiAlias

画笔是否抗锯齿

字体大小

setTextSize

设置字体到大小

字体测量

getFontMetrics()、getFontMetricsInt()

返回字体测量,返回依次为float、int

文字宽度

measureText

返回文字到宽度

文字对齐方式

setTextAlign

左对齐(LEFT)、居中对齐(CENTER)、右对齐(RIGHT)

宽度

setStrokeWidth

设置画笔宽度

笔锋

setStrokeCap

默认(BUTT),半圆形(ROUND),方形(SQUARE)

(注:因API较多,只列出常用到方法,想了解更多,请查看官方文档)

一、坐标系

1、屏幕坐标系

屏幕坐标系以手机屏幕到左上角为坐标原点,过原点的水平直线为X轴,向右为正方向;过原点的垂线为Y轴,向下为正方向;

屏幕坐标系.png

2、View坐标系

View坐标系以父视图到左上角为坐标原点,过原点的水平直线为X轴,向右为正方向;过原点的垂线为Y轴,向下为正方向

View坐标系.png

View内部拥有四个函数,用于获取View到位置

getTop(); //View的顶边到其Parent View的顶边的距离,即View的顶边与View坐标系的X轴之间的距离

getLeft(); //View的左边到其Parent View的左边的距离,即View的左边与View坐标系的Y轴之间的距离

getBottom(); //View的底边到其Parent View的顶边的距离,即View的底边与View坐标系的X轴之间的距离

getRight(); //View的右边到其Parent View的左边的距离,即View的右边与View坐标系的Y轴之间的距离

如图所示

QQ图片20170221145844.png

二、绘制过程

1、自定义属性

2、onMeasure

3、onLayout

用于确定View以及其子View的布局位置,在ViewGroup中,当位置被确定后,它在onLayout中会遍历所有到child并调用其layout,然后layout内部会再调用child到onLayout确定child view到布局位置

layout放法如下

public void layout(int l, int t, int r, int b) {

····

int oldL = mLeft;

int oldT = mTop;

int oldB = mBottom;

int oldR = mRight;

····

for (int i = 0; i < numListeners; ++i) {

listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);

}

}

}

·····

}

mLeft,mTop,mBottom,mRight四个参数分别通过getLeft(),getTop(),getBottom(),getRight(),四个函数获得,这一组old值会在位置改变时,调用onLayoutChanges时使用到

4、onSizeChanged

如其名,在View大小改变是调用此函数,用于确定View的大小。至于View大小为什么会改变,因为View的大小不仅由本身确定,同事还受父View到影响

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

}

这里到w、h就是确定后到高宽值,如果查看View中的onLayoutChange也会看到类似的情况,拥有l, t, r, b, oldL, oldT, oldR, oldB,新旧两组参数

5、onDraw

onDraw是View的绘制部分,给了我们一张空白的画布,使用Canvas进行绘制。也是后面几篇文章所要分享的内容。

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

}

6、onTouchEvent

@Override

public boolean onTouchEvent(MotionEvent event) {

return super.onTouchEvent(event);

}

当返回true时,说明该View消耗了触摸事件,后续到触摸事件由它来进行处理。返回false时,说明该View对触摸事件不感兴趣,事件继续传递下去。触屏事件类型被封装在MotionEvent中,MotionEvent提供了很多类型事件,主要关系以下几种类型:

事件类型

描述

ACTION_DOWN

手指按下

ACTION_MOVE

手指移动

ACTION_UP

手指抬起

在MotionEvent中有两组可以获得触摸位置到函数

event.getX(); //触摸点相对于View坐标系的X坐标

event.getY(); //触摸点相对于View坐标系的Y坐标

event.getRawX(); //触摸点相对于屏幕坐标系的X坐标

event.getRawY(); //触摸点相对于屏幕坐标系的Y坐标

如图所示:

触摸位置.png

onWindowFocusChanged运行于onMeasure与onLayout之后,可以获取到正确的width、height、top、left等属性值。

你可能感兴趣的:(android以view建坐标系,Android自定义View三(坐标系与View的绘制流程))