自定义View绘制

423 阅读3分钟

自定义View绘制

一、绘制的基本要素

onDraw(Canvas):做绘制需要重写的方法,可以重写的绘制方法有很多,onDraw是最基本的。

Canvas:实际用来绘制的工具,绘制时调用Canvas的各种方法来做。

Paint:调整风格如颜色或线条粗细等。

坐标系:以右为x轴,下为y轴,顺时针为正向角度。

尺寸单位:绘制时所有长度和位置的尺寸单位都是px,写xml用的是dp和sp,可以自动适配。绘制阶段是跟屏幕对话,用像素单位不同手机上展现会不一样。dp让不同的像素密度的设备物理尺寸表现基本一致。onDraw里处理的是px,需要将传入的dp值转换为px值。

二、Xfermode

在Android自定义控件或者对图片等进行处理时需要做一些图像混合的操作时,会用到xfermode。利用xfermode可以做出许多有趣的UI效果时。比如做不同形状的头像,刮刮卡。

举例,画图形A,设置xfermode的SRC_IN模式,画图形B,结果会仅显示B,因为B下面的View并不直接是A,解决方案,采用离屏缓冲,通过canvas的saveLayer,saveLayer第一个参数的bounds需要在范围上包含A和B的区域,且A和B图片范围也要包含A和B并集区域,这样A和B才能做协同计算。在离屏缓冲画A,切换xfermode模式,再画B,恢复xfermode,然后一起放在原来的显示位置,恢复离屏缓冲。

三、文字的测量

文字常用sp格式是因为在设置-显示里可以统一调节文字大小,sp同dp共同点是,在不同的像素密度的设备上会自动适配,不同点是sp还会根据用户的字体大小偏好来缩放。

文字横向居中用Paint.Align.CENTER。

横向居中,静态文字用paint.getTextBounds获取文字坐上右下四个边界的值,计算竖直中心时扣除掉文字高度的一半;动态文字用ascent和descent作为文字的顶和底。

做贴上边用于阅读的用FontMetrics的top,观赏型用bounds的top,一般不用FontMetrics的ascent。

做左贴边时,如果上下两行文字字体相差太大,会导致文字间隙不一致而看起来不对齐,需要对文字左边扣除掉bounds.left。

多行文字可用staticLayout。多行文字中间嵌套图片场景需要使用breakText,扣除图片宽度。

四、范围裁切和几何变换

范围裁切有如下方式: clipRect()、clipPath()、clipOutRect() / clipOutPath(),该方式不能去除锯齿,区别于Xfermode。

Canvas的几何变换: translate(x,y):左上右下平移

rotate(degree):指定角度旋转,或指定角度加轴心去旋转

scale(x,y):放缩

skew(x,y):错切,如正方形切成菱形

canvas坐标系和view坐标系分别是两个,旋转时需注意

Matrix的几何变换:

preTranslate(x,y) / postTranslate(x,y)

preRotate(degree) / postRotate(degree)

preScale(x,y) / postScale(x,y)

preSkew(x,y) / postSkew(x,y)