【Android 控件】实现柱状图自定义控件

一、基本思路

  • 创建自定义控件的数据模型;
  • 创建一个自定义 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。

6、LinearGradient 设置线性渐变色

  • 创建 LinearGradient 对象
    LinearGradient 是 Android 图形 API 中用于创建线性渐变效果的类。它需要指定渐变的起始点和结束点,以及渐变的颜色。
  • 设置渐变方向和颜色
    通过指定起始点和结束点的坐标,可以控制渐变的方向。颜色可以通过颜色数组指定,数组中的颜色将按照顺序渐变。
  • 将 LinearGradient 应用到 Paint 对象
    使用 Paint 对象的 setShader 方法将 LinearGradient 应用到画笔上,从而在绘制时实现渐变效果。
  • 使用 Canvas 绘制渐变
    通过 Canvas 的绘制方法(如 drawRect、drawCircle 等)绘制渐变图形。
public LinearGradient(float x0, float y0, float x1, float y1, @ColorInt int color0, @ColorInt int color1, @NonNull TileMode tile)
public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,            @Nullable float[] positions, @NonNull TileMode tile)            
  • x0 和 y0:渐变的起始点坐标;
  • x1 和 y1:渐变的结束点坐标;
  • color0 和 color1:渐变的开始颜色和结束颜色;
  • tile:渐变的平铺模式,定义了超出渐变范围的区域如何处理:
    • TileMode.CLAMP:在渐变范围外使用最近的颜色值。
    • TileMode.REPEAT:重复渐变模式。
    • TileMode.MIRROR:镜像渐变模式。
  • colors:渐变的颜色数组,数组中的颜色会按照顺序从起始点到结束点渐变。
  • positions:可选的浮点数组,定义了每个颜色在渐变中的位置,数组中的值必须在[0, 1] 范围内,表示从起始点到结束点的相对位置。如果 positions 为 null,则默认颜色均匀分布。如果 positions 不为 null,则其长度必须与 colors 的长度相同。

三、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" />
        
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值