一、基本思路
创建自定义控件的数据模型; 创建一个自定义 View 类,继承自 View; 在初始化方法中获取自定义属性的值。 创建设置数据方法,将数据模型列表转换成自定义绘制时的数据; 重写 onDraw 方法,以实现自定义的绘制逻辑。
二、主要绘制方法
1、drawLine 绘制直线
public void drawLine ( float startX, float startY, float stopX, float stopY, Paint paint)
startX 和 startY :起点的 x 和 y 坐标。 stopX 和 stopY :终点的 x 和 y 坐标。 线条的样式是 Paint.Style.STROKE 。
2、 drawLines 绘制一系列直线
public void drawLines ( @Size ( multiple = 4 ) @NonNull float [ ] pts, int offset, int count, @NonNull Paint paint)
public void drawLines ( @Size ( multiple = 4 ) @NonNull float [ ] pts, @NonNull Paint paint)
pts :包含点坐标的数组。每条线由数组中的 4 个连续值定义,例如 pts[0] 和 pts[1] 是起点,pts[2] 和 pts[3] 是终点。因此,数组的长度必须是 4 的倍数。 offset :从数组中跳过的值的数量。 count :在跳过 offset 个值后要处理的值的数量。由于每条线需要 4 个值,因此实际绘制的线条数量为 count / 4,也说明 count 值必须是 4 的倍数。 应用场景 :drawLines 方法适用于绘制简单的直线,例如:绘制网格线,绘制坐标轴,绘制界线,在游戏或图表中绘制路径。
3、drawText 绘制文本
public void drawText ( @NonNull String text, float x, float y, @NonNull Paint paint)
text :要绘制的字符串。 x 和 y :文本的起始点坐标(y 是基线的坐标)。 paint :用于绘制文本的 Paint 对象。绘制文本时,可通过设置 paint 属性来配置文本的颜色、大小、样式(粗体、斜体、下划线)等属性。
4、drawRect 绘制矩形
public void drawRect ( float left, float top, float right, float bottom, @NonNull Paint paint)
public void drawRect ( @NonNull RectF rect, @NonNull Paint paint)
left :矩形的左边界(x 坐标)。 top :矩形的上边界(y 坐标)。 right :矩形的右边界(x 坐标)。 bottom :矩形的下边界(y 坐标)。 paint :用于绘制矩形的 Paint 对象,可以设置颜色、填充方式(Paint.Style.FILL 或 Paint.Style.STROKE )、笔触宽度(strokeWidth)、边框样式等。 rect :RectF 对象,表示矩形的四个边界。 坐标系 :Android 的坐标系以屏幕左上角为原点,x 轴向右为正,y 轴向下为正。 矩形边界 :left 必须小于 right,top 必须小于 bottom,否则不会绘制任何内容。 性能优化 :如果需要频繁绘制矩形,建议在 onDraw 方法中尽量减少对象创建(如 RectF),以避免内存分配和垃圾回收。
5、Matrix 实现图形变换
在 Android 中,Matrix 类是一个强大的工具,用于处理 2D 图形变换,包括平移、缩放、旋转和倾斜等操作。Matrix 是一个 3×3 的浮点数矩阵,主要用于图像和视图的变换。
(1)缩放(Scale)
public void setScale ( float sx, float sy)
基于原点缩放 :对图像在 X 轴和 Y 轴方向进行缩放。 例如,setScale(2F, 0.5F) 表示在 X 轴方向放大 2 倍,在 Y 轴方向缩小为原来的一半。
public void setScale ( float sx, float sy, float px, float py)
基于指定点缩放 :可以指定缩放的中心点。 例如,setScale(2F, 0.5F, 600, 600) 表示以点 (600, 600) 为中心进行缩放。
(2)旋转(Rotate)
public void setRotate ( float degrees)
围绕原点旋转 :可以围绕原点进行旋转。 degrees: 旋转的度数。正数表示顺时针旋转,负数表示逆时针旋转。
public void setRotate ( float degrees, float px, float py)
围绕指定点旋转 :可以指定旋转的中心点。 例如,setRotate(-30F, 600, 600) 表示以点 (600, 600) 为中心逆时针旋转 30 度。
(3)平移(Translate)
public void setTranslate ( float dx, float dy)
平移:可以对图像进行平移操作。 例如,setTranslate(100, 50) 表示将图像向右平移 100 像素,向下平移 50 像素。
(4)倾斜(Skew)
public void setSkew ( float kx, float ky)
基于原点倾斜 :可以对图像进行倾斜操作。 kx 和 ky:kx 表示在 X 轴方向的倾斜,ky 表示在 Y 轴方向的倾斜。 例如,setSkew(30, 0, 600, 600) 表示以点(600, 600)为中心向 X 轴方向倾斜 30 度。
public void setSkew ( float kx, float ky, float px, float py)
基于指定点的倾斜 :可以指定倾斜的中心点。 例如,setSkew(30, 0, ) 表示在 X 轴方向倾斜 30 度。
(5)组合变换
Matrix 类还支持组合变换,即在一个矩阵中应用多个变换操作。
val matrix = Matrix ( ) matrix. postScale ( 1.5F , 0.5F ) matrix. postRotate ( 30F ) matrix. postTranslate ( 500F , 200F )
setRotate :当你需要从头开始设置一个旋转,且不关心之前的变换状态时,使用 setRotate。 postRotate :当你需要在现有变换的基础上追加一个旋转操作时,使用 postRotate。
三、demo 示例
1、数据模型定义
data class ChartModel ( val label: String, val value: Int)
2、res/values/attrs.xml 中自定义属性
< declare- styleable name= "BarChartView" > < attr name= "android:max" format= "integer" / > < attr name= "android:textSize" format= "dimension" / > < attr name= "android:textColor" format= "color" / > < ! -- 0 - 倾斜日期模式 1 - 简便日期模式 -- > < attr name= "mode" format= "integer" / > < / declare- styleable>
3、自定义柱状图控件
package com. android. androidfunctiondemo. customviewimport android. animation. ValueAnimator
import android. annotation. SuppressLint
import android. content. Context
import android. graphics. Canvas
import android. graphics. LinearGradient
import android