<font style="text-shadow:0px 0px 15px #FF37FD;">Canvas</font> === ###### tags: `Android developer` `Kotlin` <font color="Brown">android.graphics.Canvas</font> <font color="Brown">畫布,要在上面繪製東西需要四個基本組件。 一個點陣圖,一個調用點陣圖,一個繪圖基元(矩形、路徑、文字、點陣圖),還有一個Pain(繪圖的顏色和樣式)</font> ## <font color="sandybrown">Constructors</font> ### <font color="#990DFF">Canvas( )</font> ### <font color="#990DFF">Canvas(Bitmap bitmap)</font> ## <font color="sandybrown">方法</font> ### <font color="#990DFF">drawColor(color: Int): Unit</font> :::info 使用指定顏色 ::: :::success **參數** color : 繪製到畫布上的顏色 ::: :::warning **Ex:** ```kotlin= canvas?.drawColor(Color.RED) ``` ::: ### <font color="#990DFF">drawARGB(a: Int, r: Int, g: Int, b: Int): Unit</font> :::info 指定的ARGB顏色填充整個畫布 ::: :::success **參數** a : 要繪製到畫布上的顏色的alpha分量(0..255) r : 要繪製到畫布上的顏色的紅色成分(0..255) g : 要繪製到畫布上的顏色的綠色成分(0..255) b : 要繪製到畫布上的顏色的藍色分量(0..255) ::: :::warning **Ex:** ```kotlin= canvas?.drawARGB(0xFF,0xFF,0,0xFF) ``` ::: ### <font color="#990DFF">drawRGB(r: Int, g: Int, b: Int): Unit</font> :::info 指定的RGB顏色填充整個畫布 ::: :::success **參數** r : 要繪製到畫布上的顏色的紅色分量(0..255) g : 要繪製到畫布上的顏色的綠色成分(0..255) b : 要繪製到畫布上的顏色的藍色分量(0..255) ::: :::warning **Ex:** ```kotlin= canvas?.drawRGB(0xFF,0x00,0xFF) ``` ::: ### <font color="#990DFF">drawLine(startX: Float, startY: Float, stopX: Float, stopY: Float, paint: Paint): Unit</font> :::info 使用指定的繪製,使用指定的開始和停止x,y坐標繪製線段。 ::: :::success **參數** startX : 線的起點的x坐標 startY : 線的起點的y坐標 paint : 用於繪製線條的繪製,此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint=Paint().apply { color=Color.RED strokeWidth=50f } canvas?.drawLine(100f,100f,200f,200f,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/5ij7S9r.png) ::: ### <font color="#990DFF">drawLines(pts: FloatArray, paint: Paint): Unit</font> :::info 畫出一系列線條。每行取自pts數組中的4個連續值。因此,為了繪製1行,該數組必須包含至少4個值。這在邏輯上與繪製數組相同如下:drawLine(pts [0],pts [1],pts [2],pts [3]),然後是drawLine(pts [4],pts [5],pts [ [6],pts [7])等。 ::: :::success **參數** pts : 要繪製的點數組[x0 y0 x1 y1 x2 y2 ...]此值絕不能為null。 paint : 用於繪製點的繪製此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint=Paint().apply { color=Color.RED strokeWidth=5f } canvas?.drawLines(floatArrayOf(10f,10f,100f,100f,200f,200f,400f,400f),paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/FyiXTdb.png) ::: ### <font color="#990DFF">drawLines(pts: FloatArray, offset: Int, count: Int, paint: Paint): Unit</font> :::info 畫出一系列線條。每行取自pts數組中的4個連續值。因此,為了繪製1行,該數組必須包含至少4個值。這在邏輯上與繪製數組相同如下:drawLine(pts [0],pts [1],pts [2],pts [3]),然後是drawLine(pts [4],pts [5],pts [ [6],pts [7])等。 ::: :::success **參數** pts : 要繪製的點數組[x0 y0 x1 y1 x2 y2 ...]此值絕不能為null。 offset : 繪製前要跳過的數組中的值數。 count : 跳過它們的“偏移”後要處理的數組中的值的數量。由於每行使用4個值,因此繪製的“行”數確實是(count >> 2)。 paint : 用於繪製點的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.RED strokeWidth = 5f } // offet=2,count=4 -> 從 pet[2] 開始到 pet[5] 結束 // (100,100) 畫到 (200,200) canvas?.drawLines(floatArrayOf(10f, 10f, 100f, 100f, 200f, 200f, 400f, 400f), 2,4,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/saNrR7D.png) ::: ### <font color="#990DFF">drawPoint(x: Float, y: Float, paint: Paint): Unit </font> :::info 繪製單個點 ::: :::success **參數** x : 點的 X 座標。 y : 點的 Y 座標。 paint : 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.RED strokeWidth = 15f } canvas?.drawPoint(100f,100f,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/wcLjjQz.png) ::: ### <font color="#990DFF">drawPoints(pts: FloatArray!, offset: Int, count: Int, paint: Paint): Unit </font> :::info 繪製多個點,每個點都以pts []指定的坐標為中心,其直徑由繪畫的筆觸寬度指定,特殊處理筆劃寬度為0。 ::: :::success **參數** pts : 要繪製的點數組[x0 y0 x1 y1 x2 y2 ...] offset : 開始繪製前要跳過的值的數量。 count : 跳過它們的偏移量後要處理的值的數量。由於一個點使用兩個值,因此繪製的“點”數確實是(count >> 1)。 paint : 用於繪製點的繪製此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.RED strokeWidth = 25f } // offet=2,count=4 -> 從 pet[2] 開始到 pet[5] 結束 // (100,100) 畫到 (200,200) canvas?.drawPoints(floatArrayOf(10f,10f,100f,100f,200f,200f,400f,400f),2,4,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/vn27YRh.png) ::: ### <font color="#990DFF">drawPoints(pts: FloatArray, paint: Paint): Unit </font> :::info 繪製多個點,每個點都以pts []指定的坐標為中心,其直徑由繪畫的筆觸寬度指定,特殊處理筆劃寬度為0。 ::: :::success **參數** pts : 要繪製的點數組[x0 y0 x1 y1 x2 y2 ...] paint : 用於繪製點的繪製此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.RED strokeWidth = 25f } // offet=2,count=4 -> 從 pet[2] 開始到 pet[5] 結束 // (100,100) 畫到 (200,200) canvas?.drawPoints(floatArrayOf(10f,10f,100f,100f,200f,200f,400f,400f),2,4,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/ESHZOdy.png) ::: ### <font color="#990DFF">drawRect(left: Float, top: Float, right: Float, bottom: Float, paint: Paint): Unit</font> :::info 指定的 Paint 繪製指定的矩形。矩形將根據繪畫中的樣式填充或加框。 ::: :::success **參數** left : 要繪製的矩形的左側 top : 要繪製的矩形的頂部 right : 要繪製的矩形的右側 bottom : 要繪製的矩形的底邊 paint : 用於繪製矩形的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 直接構造 val paint=Paint().apply { color=Color.RED style=Paint.Style.FILL canvas?.drawRect(50f,50f,200f,200f,paint) // 間接構造 val paint=Paint().apply { color=Color.RED style=Paint.Style.FILL } val rect= RectF(50f,50f,100f,100f) canvas?.drawRect(rect, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/3Rc40tA.png) ::: ### <font color="#990DFF">drawRect(rect: RectF, paint: Paint): Unit</font> :::info 指定的 Paint 繪製指定的矩形。矩形將根據繪畫中的樣式填充或加框。 ::: :::success **參數** rect : 要繪製的矩形此值絕不能是null。 paint : 用於繪製矩形的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint=Paint().apply { color=Color.RED style=Paint.Style.FILL } val rect= RectF(50f,50f,100f,100f) canvas?.drawRect(rect, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/3Rc40tA.png) ::: ### <font color="#990DFF">drawRect(r: Rect, paint: Paint): Unit</font> :::info 指定的 Paint 繪製指定的矩形。矩形將根據繪畫中的樣式填充或加框。 ::: :::success **參數** rect : 要繪製的矩形此值絕不能是null。 paint : 用於繪製矩形的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint=Paint().apply { color=Color.RED style=Paint.Style.FILL } val r= Rect(50,50,100,100) canvas?.drawRect(r, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/3Rc40tA.png) ::: ### <font color="#990DFF">drawRoundRect(rect: RectF, rx: Float, ry: Float, paint: Paint): Unit</font> :::info 指定的 Paint 繪製指定的圓形矩形。圓形將根據油漆中的樣式填充或框起。 ::: :::success **參數** rect : 要繪製的矩形此值絕不能是null。 rx : 用於圓角的橢圓的x半徑 ry : 用於圓角的橢圓的y半徑 paint : 用於繪製圓角矩形的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint=Paint().apply { color=Color.RED style=Paint.Style.FILL } val r= RectF(100f,10f,300f,100f) canvas?.drawRoundRect(r, 20f,10f,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/6FrUmB1.png) ::: ### <font color="#990DFF">drawCircle(cx: Float, cy: Float, radius: Float, paint: Paint): Unit</font> :::info 指定的 Paint 畫出指定的圓。如果radius <= 0,則不會繪製任何內容。圓圈將根據油漆中的樣式填充或加框。 ::: :::success **參數** cx : 要繪製的圓心的x坐標 cy : 要繪製的圓心的y坐標 radius : 要繪製的圓的半徑 paint : 用於繪製圓的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint=Paint().apply { color=Color.RED style=Paint.Style.FILL } canvas?.drawCircle(190f, 200f,150f,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/ppNHps4.png) ::: ### <font color="#990DFF">drawOval(oval: RectF, paint: Paint): Unit</font> :::info 指定的 Paint 繪製指定的橢圓。橢圓形將根據油漆中的樣式填充或框起。 ::: :::success **參數** oval : 要繪製的橢圓的矩形邊界此值絕不能為null。 paint : 用於繪製橢圓的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint = Paint().apply { color = Color.RED style = Paint.Style.STROKE strokeWidth = 5f } // 畫矩形 val rect = RectF(50f, 50f, 300f, 200f) canvas?.drawRect(rect, paint) // 畫橢圓 paint.color = Color.GREEN canvas?.drawOval(rect, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/6GHF1CR.png) ::: ### <font color="#990DFF">drawOval(left: Float, top: Float, right: Float, bottom: Float, paint: Paint): Unit</font> :::info 指定的 Paint 繪製指定的橢圓。橢圓形將根據油漆中的樣式填充或框起。 ::: :::success **參數** left : 要繪製的橢圓的左側 top : 要繪製的橢圓的頂部 right : 要繪製的橢圓的右側 bottom : 要繪製的橢圓的底邊 paint : 用於繪製橢圓的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint = Paint().apply { color = Color.RED style = Paint.Style.STROKE strokeWidth = 5f } canvas?.drawOval(50f, 50f, 300f, 200f,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/vKWj8PX.png) ::: ### <font color="#990DFF">drawArc(oval: RectF, startAngle: Float, sweepAngle: Float, useCenter: Boolean, paint: Paint): Unit</font> :::info 繪製指定的弧,將縮放以適合指定的橢圓內部。 如果起始角度為負或> = 360,則將起始角度視為起始角度模360。 如果掃掠角度> = 360,則完全繪製橢圓。請注意,這與SkPath :: arcTo略有不同,後者將掃描角度模數設為360.如果掃描角度為負,則掃描角度將被視為掃描角度模數360 順時針繪製弧線。0度的角度對應於0度的幾何角度(手錶上的3點鐘)。 ::: :::success **參數** oval : 橢圓的邊界,用於定義弧的形狀和大小。該值絕不能是null。 startAngle : 弧開始的起始角度(以度為單位) sweepAngle : 順時針測量的掃描角度(以度為單位) useCenter : 如果為true,則在弧形中包含橢圓的中心,如果正在描邊則將其關閉。 paint : 用於繪製橢圓的 Paint 此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= // 間接構造 val paint = Paint().apply { color = Color.RED style = Paint.Style.STROKE strokeWidth = 5f } val ovalUseCenter = RectF(10f, 10f, 100f, 100f) canvas?.drawRect(ovalUseCenter, paint) paint.color = Color.GREEN canvas?.drawArc(ovalUseCenter, 0f, 90f, true, paint) paint.color = Color.RED val ovalNoUseCenter = RectF(110f, 10f, 200f, 100f) canvas?.drawRect(ovalNoUseCenter, paint) paint.color = Color.GREEN canvas?.drawArc(ovalNoUseCenter, 0f, 90f, false, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/6LREQIg.png) ::: ### <font color="#990DFF">drawText(text: String, x: Float, y: Float, paint: Paint): Unit</font> :::info 指定的 Paint 繪製文本,原點為(x,y)。 ::: :::success **參數** text : 要繪製的文本此值絕不能是null。 x : 正在繪製的文字原點的x坐標 y : 正在繪製的文字的基線的y坐標 paint : 用於文字的 Paint(例如顏色,大小,樣式)此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= canvas?.drawText("Hello world",100f,400f,paint) ``` ::: ### <font color="#990DFF">drawText(text: CharSequence, start: Int, end: Int, x: Float, y: Float, paint: Paint): Unit</font> :::info 指定的 Paint 中繪製由start / end指定的文本的指定範圍,其原點為(x,y)。 ::: :::success **參數** text : 要繪製的文本此值絕不能是null。 start : 要繪製的文本中第一個字符的索引 end : ( end - 1)是要繪製的文本中最後一個字符的索引 x : 正在繪製的文字原點的x坐標 y : 正在繪製的文字的基線的y坐標 paint : 用於文字的 Paint(例如顏色,大小,樣式)此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= canvas?.drawText("Helloworld",0,7,100f,400f,paint) ``` ::: ### <font color="#990DFF">drawText(text: String, start: Int, end: Int, x: Float, y: Float, paint: Paint): Unit</font> :::info 指定的 Paint 中繪製由start / end指定的文本的指定範圍,其原點為(x,y)。 ::: :::success **參數** text : 要繪製的文本此值絕不能是null。 start : 要繪製的文本中第一個字符的索引 end : ( end - 1)是要繪製的文本中最後一個字符的索引 x : 正在繪製的文字原點的x坐標 y : 正在繪製的文字的基線的y坐標 paint : 用於文字的 Paint(例如顏色,大小,樣式)此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= canvas?.drawText("Helloworld",0,7,100f,400f,paint) ``` ::: ### <font color="#990DFF">drawTextOnPath(text: String, path: Path, hOffset: Float, vOffset: Float, paint: Paint): Unit</font> :::info 指定的 Paint 沿指定路徑繪製原點為(x,y)的文字。 ::: :::success **參數** text : 要繪製的文字此值絕不能是null。 path : 文字應該遵循其基線的路徑此值絕不能是null。 hOffset : 沿路徑添加到文字起始位置的距離 vOffset : 位於文字位置的路徑上方( - )或下方(+)的距離 paint : 用於文字的 Paint(例如顏色,大小,樣式)此值絕不能是null。 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color=Color.RED style=Paint.Style.STROKE strokeWidth=5f textSize=45f } val circlePath=Path().apply { addCircle(220f,300f,150f,Path.Direction.CCW) } canvas?.drawPath(circlePath,paint) val circlePath2=Path().apply { addCircle(600f,300f,150f,Path.Direction.CCW) } canvas?.drawPath(circlePath2,paint) val string="沿路徑繪製範例" paint.color=Color.GREEN canvas?.drawTextOnPath(string,circlePath,0f,0f,paint) canvas?.drawTextOnPath(string,circlePath2,80f,30f,paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/rIfg3iF.png) ::: ### <font color="#990DFF">translate(dx: Float, dy: Float): Unit</font> :::info 指定平移 ::: :::success **參數** dx : 在X中平移的距離 dy : 在Y中平移的距離 ::: :::warning **Ex:** ```kotlin= val paint=Paint().apply { color=Color.GREEN style=Paint.Style.FILL } // 平移 X 往右 100 // 平移 Y 往下 100 canvas?.translate(100f,100f) canvas?.drawRect(0f,0f,canvas.width.toFloat(),canvas.height.toFloat(),paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/i1QXpUr.png) ::: ### <font color="#990DFF">rotate(degrees: Float): Unit</font> :::info 預先指定具有指定旋轉的當前矩陣。 ::: :::success **參數** degrees : 旋轉的數量,以度為單位 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.BLUE style = Paint.Style.STROKE strokeWidth = 5f } // 還沒旋轉 val rect = Rect(300, 10, 500, 100) canvas?.drawRect(rect, paint) paint.apply { color = Color.RED style = Paint.Style.FILL } // cavas 原點旋轉 canvas?.rotate(30f) canvas?.drawRect(rect, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/0HvmV0Z.png) ::: ### <font color="#990DFF">rotate(degrees: Float, px: Float, py: Float): Unit</font> :::info 預先指定具有指定旋轉的當前矩陣。 ::: :::success **參數** degrees : 旋轉的數量,以度為單位 px : 樞軸點的x-coord(由旋轉不變) py : 樞軸點的y坐標(由旋轉不變) ::: ### <font color="#990DFF">scale(sx: Float, sy: Float): Unit</font> :::info 指定具有指定比例的當前矩陣。 ::: :::success **參數** sx : X中的縮放量 sy : Y中的擴展量 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.BLUE style = Paint.Style.STROKE strokeWidth = 5f } // 原比例 val rect = Rect(50, 50, 250, 150) canvas?.drawRect(rect, paint) paint.apply { color = Color.RED } // 縮小 canvas?.scale(0.5f,1f) canvas?.drawRect(rect, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/lynbOSn.png) ::: ### <font color="#990DFF">scale(sx: Float, sy: Float, px: Float, py: Float): Unit</font> :::info 指定具有指定比例的當前矩陣。 ::: :::success **參數** sx : X中的縮放量 sy : Y中的擴展量 px : 樞軸點的x-coord(由比例不變) py : 樞軸點的y坐標(由比例不變) ::: ### <font color="#990DFF">skew(sx: Float, sy: Float): Unit</font> :::info 預先指定具有指定偏斜的當前矩陣。 ::: :::success **參數** sx : X中傾斜的數量 sy : Y中傾斜的數量 ::: :::warning **Ex:** ```kotlin= val paint = Paint().apply { color = Color.BLUE style = Paint.Style.STROKE strokeWidth = 5f } val rect = Rect(100, 100, 300, 200) canvas?.drawRect(rect, paint) paint.apply { color = Color.RED } // 繞X軸傾斜60度 canvas?.skew(Math.tan(2 * Math.PI / 360 * 60).toFloat(), 0f) canvas?.drawRect(rect, paint) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/7t0a7Ho.png) ::: ### <font color="#990DFF">clipRect(rect: Rect): Boolean</font> :::info 將當前剪輯與指定的矩形相交,該矩形以本地坐標表示。 ::: :::success **參數** rect : 與當前剪輯相交的矩形。絕不能是這個值null。 sy : Y中傾斜的數量 ::: :::warning **Ex1:** ```kotlin= canvas?.drawColor(Color.RED) canvas?.clipRect(Rect(100,100,200,200)) canvas?.drawColor(Color.GREEN) ``` :::danger **輸出結果 :** ![](https://i.imgur.com/sPpsFdY.png) ::: :::warning **Ex2: 圓形裁切** ```kotlin= class ClipCircle(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private var bitmap: Bitmap private var paint: Paint? private var path: Path private var centerX = 50f private var centerY = 50f init { bitmap = BitmapFactory.decodeResource(resources, R.drawable.circle_test) paint = Paint() path = Path() path.addCircle(bitmap.width / 2f +centerX, bitmap.height / 2f+centerY , bitmap.width / 2f, Path.Direction.CCW) } override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) canvas?.clipPath(path) canvas?.drawBitmap(bitmap, centerX, centerY, paint) } } ``` :::danger **輸出結果 :** ![](https://i.imgur.com/MlQGSl2.png) ::: ### <font color="#990DFF">save(): Int</font> :::info 將當前矩陣和剪輯保存到專用堆棧。 後續調用translate,scale,rotate,skew,concat或clipRect,clipPath都將照常運行,但是當進行restore()的平衡調用時,將忘記這些調用,以及save()之前存在的設置將恢復。 ::: ### <font color="#990DFF">restore(): Unit</font> :::info 此調用平衡先前對save()的調用,並用於刪除自上次保存調用以來對矩陣/剪輯狀態的所有修改。調用restore()的次數比調用save()的次數多出錯。 ::: :::warning **Ex:** ```kotlin= // 儲存當前的畫布 canvas?.save() canvas?.clipRect(Rect(100,100,800,800)) canvas?.drawColor(Color.GREEN) // 恢復之前存的畫布 canvas?.restore() canvas?.drawColor(Color.BLUE) ``` :::