一、基本思路
創建自定義控件的數據模型; 創建一個自定義 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