來(lái)自https://juejin.im/post/5d61514df265da03d60f0ab6#heading-6
[圖片上傳失敗...(image-5c215-1566990678513)]
前言
1. 文章內(nèi)容
這篇文章分為下面 5 個(gè)部分含思。
-
繪圖基礎(chǔ)
這一節(jié)會(huì)介紹 Android 中的畫(huà)筆 Paint 和畫(huà)布 Canvas 的用法。
-
路徑繪制
這一節(jié)會(huì)介紹 Android 中路徑 Path 的用法甘晤,包括直線含潘、弧線和雷達(dá)圖等圖形的繪制方法。
-
文字繪制
這一節(jié)會(huì)介紹 Android 中繪制文字的方法线婚,包括粗體遏弱、斜體、加載字體等塞弊。
-
區(qū)域操作
這一節(jié)會(huì)介紹 Android 中區(qū)域 Region 的用法漱逸,包括區(qū)域裁剪、區(qū)域合并等操作游沿。
-
畫(huà)布進(jìn)階
這一節(jié)會(huì)對(duì)畫(huà)布的用法進(jìn)行更詳細(xì)的介紹饰抒,包括保存、指向恢復(fù)和圓形頭像奏候。
2. 注意事項(xiàng)
-
對(duì)象創(chuàng)建
下面的示例代碼會(huì)在 onDraw() 方法中創(chuàng)建 Paint循集、Path唇敞、Rect 和 Region等對(duì)象蔗草,這在實(shí)際開(kāi)發(fā)中是禁止的咒彤。
因?yàn)楫?dāng) View 需要重繪時(shí)會(huì)調(diào)用 onDraw() 函數(shù),每一次調(diào)用 onDraw() 函數(shù)都會(huì)重新創(chuàng)建這些對(duì)象咒精。
這樣會(huì)引起頻繁的 GC镶柱,嚴(yán)重時(shí)會(huì)導(dǎo)致 App 卡頓。
-
圖片清晰度
點(diǎn)擊文章中的圖片可以查看原圖模叙。
-
示例代碼
文中的示例代碼源碼在文章最下方可以找到歇拆。
1. 繪圖基礎(chǔ)
本節(jié)包含內(nèi)容如下。
- 畫(huà)筆用法
- 畫(huà)布用法
- 顏色構(gòu)造
1.1 畫(huà)筆用法
我們這一節(jié)來(lái)看一下畫(huà)筆的用法范咨。
本節(jié)包含內(nèi)容如下故觅。
- 設(shè)置畫(huà)筆顏色
- 設(shè)置畫(huà)筆樣式
- 設(shè)置畫(huà)筆寬度
- 設(shè)置畫(huà)筆鋸齒
1.1.1 設(shè)置畫(huà)筆顏色
[圖片上傳失敗...(image-4cbe4a-1566990678513)]
Paint 的 setColor(int color) 方法可用于設(shè)置畫(huà)筆顏色,下面是 color 參數(shù)的取值渠啊。
一種顏色是由紅綠藍(lán)三色合成的输吏,所以 color 只能取 8 位 0xAARRGGBB 樣式顏色值。
-
透明度
A 表示透明度 Alpha替蛉,取值范圍是 0~255贯溅,值越小,圖像越透明
-
紅色
R 表示紅色 Red躲查,取值范圍是 0~255它浅,取值越小紅色越少
-
綠色
G 表示綠色 Green,取值范圍是 0~255镣煮,取值越小綠色越少
-
藍(lán)色
B 表示藍(lán)色 Blue姐霍,取值范圍是 0~255,取值越小藍(lán)色越少
除了手動(dòng)組合顏色怎静,系統(tǒng)還提供了一個(gè)用于解析顏色的類 Color邮弹,關(guān)于 Color 在后面會(huì)有更詳細(xì)的介紹。
1.1.2 設(shè)置畫(huà)筆樣式
[圖片上傳失敗...(image-270598-1566990678513)]
Paint 的 setStyle(Style style) 方法可用于設(shè)置畫(huà)筆樣式蚓聘,下面是 style 參數(shù)的取值腌乡。
-
描邊
- STROKE
-
填充
- FILL
默認(rèn)樣式。
-
描邊且填充
- FILL_AND_STROKE
描邊與填充疊加在一起顯示的效果夜牡,也就是這個(gè)值比填充多了一個(gè)描邊的寬度与纽。
1.1.3 設(shè)置畫(huà)筆寬度
Paint 的 setStrokeWidth(width) 方法用于設(shè)置描邊寬度,單位是 px塘装。
-
注意事項(xiàng)
當(dāng)畫(huà)筆的 Style 是 STROKE 或 FILL_AND_STROKE 時(shí)畫(huà)筆寬度才有意義急迂。
1.1.4 設(shè)置畫(huà)筆鋸齒
畫(huà)筆 Paint 繪制圖形時(shí)默認(rèn)不是抗鋸齒的,也就是邊邊會(huì)有鋸齒蹦肴。
Paint 提供了 setAntiAlias() 方法僚碎,這個(gè)方法可以開(kāi)啟畫(huà)筆的抗鋸齒功能。
下面是兩個(gè)放大后的圓阴幌,右邊的圓用的是抗鋸齒的畫(huà)筆繪制的勺阐。
[圖片上傳失敗...(image-a15b4b-1566990678513)]
1.2 畫(huà)布用法
上一節(jié)演示畫(huà)筆的同時(shí)也演示了畫(huà)布繪制圓的方法卷中,這一節(jié)我們來(lái)看一下畫(huà)布的其他方法。
本節(jié)內(nèi)容如下渊抽。
- 設(shè)置背景
- 繪制直線
- 繪制點(diǎn)
- 矩形結(jié)構(gòu)
- 繪制矩形
- 圓角矩形
1.2.1 設(shè)置背景
Canvas 提供了三個(gè)設(shè)置背景的方法蟆豫。
- drawColor(int color)
- drawARGB(int a, int r, int g, int b)
- drawRGB(int r, int g, int b)
需要注意的是,設(shè)置畫(huà)布背景要在其他圖形繪制前設(shè)置懒闷,否則設(shè)置好的背景色會(huì)覆蓋原有的圖形十减。
[圖片上傳失敗...(image-e905b9-1566990678513)]
1.2.2 繪制直線
[圖片上傳失敗...(image-6424c4-1566990678513)]
Canvas 的 drawLine() 方法可以繪制直線,直線的粗細(xì)取決于 Paint 的 setStrokeWith(width) 中傳入的寬度愤估。
繪制直線需要注意的是帮辟,只有當(dāng) Style 是 STROKE、FILL_AND_STROKE 時(shí)繪制才有效玩焰。
- drawLine(float startX, float starY, float stopX, float stopY, Paint paint)
1.2.3 繪制點(diǎn)
[圖片上傳失敗...(image-152094-1566990678513)]
Canvas 的 drawPoint() 方法可以用于繪制點(diǎn)织阅,點(diǎn)的大小取決于 setStrokeWith(width) 中傳入的寬度。
- drawPoint(float x, float y, Paint paint)
1.2.4 矩形結(jié)構(gòu)
矩形結(jié)構(gòu)在繪制矩形區(qū)域的時(shí)候需要用到震捣。
Android 提供了 Rect 和 RectF 類用于存儲(chǔ)矩形數(shù)據(jù)結(jié)構(gòu)荔棉,下面是 Rect 和 RectF 的構(gòu)造函數(shù)。
[圖片上傳失敗...(image-1c2284-1566990678513)]
Rect 和 RectF 在于存儲(chǔ)的數(shù)據(jù)類型不同蒿赢。
-
Rect
用于保存 int 類型數(shù)值的矩形結(jié)構(gòu)
-
RectF
用于保存 float 類型數(shù)值的矩形結(jié)構(gòu)
1.2.5 繪制矩形
[圖片上傳失敗...(image-3b5c2a-1566990678513)]
Canvas 的 drawPoint() 和 drawRect() 方法都可用于繪制矩形润樱。
下面是這兩個(gè)方法的區(qū)別。
-
形狀
-
drawPoint()
只能指定矩形中心的坐標(biāo)羡棵,只能畫(huà)出正方形壹若。
-
drawRect()
需要指定矩形左上和右下兩個(gè)點(diǎn)的位置,可以是長(zhǎng)方形皂冰。
-
-
樣式
-
drawPoint()
只能是填充樣式店展。
-
drawRect()
可以自己選擇樣式,可以是描邊也可以是填充秃流。
-
下面是 Canvas 中提供用于繪制矩形的三個(gè)方法赂蕴。
- drawRect(float left, float top, float right, float bottom, Paint paint)
- drawRect(RectF rect, Paint paint)
- drawRect(Rect r, Paint paint)
1.2.6 圓角矩形
Canvas 中提供了一個(gè) drawRoundRect 方法用于繪制圓角矩形,圓角矩形的四個(gè)角是橢圓的一角舶胀,下面是它的基本用法概说。
[圖片上傳失敗...(image-406e14-1566990678513)]
1.3 顏色構(gòu)造
Color 類是 Android 中與顏色有關(guān)的類。
本節(jié)內(nèi)容如下嚣伐。
- 顏色常量
- 構(gòu)造顏色
1.3.1 顏色常量
Color 中定義了下面的顏色常量值糖赔。
[圖片上傳失敗...(image-48c6cd-1566988049043)]
1.3.2 構(gòu)造顏色
除了顏色常量外,Color 還提供了一些構(gòu)造顏色的方法轩端。
[圖片上傳失敗...(image-5ad560-1566988049043)]
alpha << 就是進(jìn) 24 位放典,當(dāng)我們調(diào)用 Color.argb(255, 0, 0,0 0) 時(shí),轉(zhuǎn)換后的 16 進(jìn)制顏色值就是 0xFF000000。
[圖片上傳失敗...(image-dd67eb-1566988049043)]
2. 路徑繪制
路徑 Path 指的是畫(huà)筆畫(huà)出來(lái)的一條不間斷的曲線奋构,本節(jié)會(huì)講解直線和弧線路徑骨田,除了這兩種方式外還有很多方法可以實(shí)現(xiàn)很多效果。
drawPath 是 Canvas 繪制路徑的方法声怔。
- drawPath(Path path, Paint paint)
本節(jié)內(nèi)容如下。
- 直線路徑
- 弧線路徑
- 添加路徑
- 填充路徑
- 重置路徑
- 雷達(dá)路徑
2.1 直線路徑
[圖片上傳失敗...(image-324557-1566988049043)]
上面是一段繪制直線路徑的代碼舱呻,這里需要注意的是醋火,上面代碼中的畫(huà)筆樣式設(shè)為描邊,默認(rèn)是填充的箱吕。
也就是在默認(rèn)情況下芥驳,多條線相連形成閉環(huán)后,中間的區(qū)域會(huì)被填充茬高。
繪制直線路徑涉及:起點(diǎn)兆旬、終點(diǎn)和閉環(huán)。
-
起點(diǎn)
Path 的 moveTo() 用于指定直線路徑的起點(diǎn)怎栽,參數(shù) x1 和 y1 是起點(diǎn)坐標(biāo)值丽猬。
- moveTo(float x1, float y1)
-
終點(diǎn)
Path 的 lineTo() 用于指定直線路徑的起點(diǎn),參數(shù) x2 和 y2 是終點(diǎn)坐標(biāo)值熏瞄,也是下一次繪制直線的起點(diǎn)脚祟。
- lineTo(float x2, float y2)
-
閉環(huán)
Path 的 close() 方法用于形成閉環(huán)。
- close()
如果連續(xù)畫(huà)了幾條直線强饮,但沒(méi)有形成閉環(huán)由桌,調(diào)用 close() 函數(shù)會(huì)把路徑首尾連接起來(lái)形成閉環(huán),相當(dāng)于是幫我們畫(huà)多一條直線邮丰。
如果只畫(huà)了一條直線行您,那 close() 方法是不會(huì)起作用的。
2.2 弧線路徑
Path 的 arcTo() 方法可用于繪制弧線剪廉,弧線在這里指的是橢圓上截取的一部分娃循。
- arcTo(RectF oval, float startAngle, sweepAngle)
本節(jié)內(nèi)容如下。
- 弧線樣式
- 弧線起點(diǎn)
- 弧線角度
- 弧線函數(shù)
2.2.1 弧線樣式
這里的橢圓底色默認(rèn)是不存在的斗蒋,在這里畫(huà)出來(lái)主要是為了突出弧線淮野。
在這里我們要注意的是,弧線默認(rèn)是填充的吹泡,更準(zhǔn)確的來(lái)說(shuō) drawArc() 方法是切出橢圓中的一塊骤星。
如果我們只想要一條線的話,就要自己設(shè)置描邊樣式和描邊寬度爆哑。
[圖片上傳失敗...(image-9a09fc-1566988049043)]
2.2.2 弧線起點(diǎn)
除了樣式以外洞难,繪制弧線要注意的另外一點(diǎn)就是起點(diǎn)。
-
改變起點(diǎn)
如果我們調(diào)用了 moveTo() 改變了路徑的起點(diǎn)揭朝,那弧線就會(huì)從 moveTo() 接收到的坐標(biāo)開(kāi)始繪制队贱。
-
重置起點(diǎn)
如果我們想重置起點(diǎn)到弧線正常該開(kāi)始的位置色冀,我們可以把 forceMoveTo 設(shè)為 true。
[圖片上傳失敗...(image-e83d85-1566988049043)]
2.2.3 弧線角度
arcTo 中有兩個(gè)跟角度有關(guān)的參數(shù) startAngle 和 sweepAngle柱嫌,這兩個(gè)參數(shù)分別代表起始角和掃描角锋恬。
-
起始角
起始角指定弧線從哪里開(kāi)始畫(huà)起。
-
掃描角
掃描角可以看成是弧線的長(zhǎng)度编丘。
[圖片上傳失敗...(image-c5c230-1566988049043)]
2.2.4 弧線函數(shù)
[圖片上傳失敗...(image-bc106-1566988049043)]
Path 中定義了的三個(gè) arcTo() 函數(shù)与学,下面是 arcTo() 函數(shù)中主要四個(gè)參數(shù)的含義。
-
oval
生成橢圓的矩形
-
startAngle
弧開(kāi)始的角度嘉抓,以 X 軸正方向?yàn)?0°
-
sweepAngle
弧持續(xù)的角度
-
forceMoveTo
重置起點(diǎn)索守,把繪制弧線的起點(diǎn)從 moveTo 的坐標(biāo)重置到 startAngle 的位置。
2.3 添加路徑
本節(jié)內(nèi)容如下抑片。
- 路徑添加方法
- 路徑繪制方向
2.3.1 路徑添加方法
Path 提供了 addXXX 函數(shù)用于添加路徑卵佛,添加的路徑可以是不連續(xù)的,還可以是曲線敞斋。
下面是 Path 中提供的一些添加路徑的方法截汪。
[圖片上傳失敗...(image-afc2b1-1566988049043)]
下面是添加路徑的示例。
[圖片上傳失敗...(image-2ae3dd-1566988049043)]
2.3.2 路徑繪制方向
在添加路徑的函數(shù)中有一些函數(shù)有 Direction 參數(shù)植捎,這個(gè) Direction 就是繪制的方向挫鸽。
方向分為順時(shí)針逆時(shí)針 CCW(Counter-Clockwise)。
[圖片上傳失敗...(image-294b7d-1566988049043)]
下面是不同方向的繪制示例鸥跟,這個(gè)示例中用到了 drawTextOnPath 方法丢郊,這個(gè)方法在講繪制文字的時(shí)候會(huì)有更詳細(xì)的介紹,現(xiàn)在我們先看繪制方向?qū)L制效果的影響医咨。
[圖片上傳失敗...(image-7b16ad-1566988049043)]
2.4 填充路徑
路徑 Path 的填充模式與畫(huà)筆 Paint 的填充模式不同枫匾,Path 的填充模式是指填充 Path 的哪部分。
在 Path 中有一個(gè) FillType 枚舉類拟淮,其中定義了 4 種填充類型干茉。
[圖片上傳失敗...(image-84560-1566988049043)]
下面是這四種填充類型的示例。
[圖片上傳失敗...(image-b4dbd9-1566988049043)]
2.5 重置路徑
Android 提供了兩個(gè)重置路徑的方法很泊,讓我們可以重復(fù)使用 Path 對(duì)象角虫。
路徑 Path 一旦被重置,其中保存的所有路徑都會(huì)被清空委造,這樣就不需要重新創(chuàng)建一個(gè) Path 對(duì)象了戳鹅。
-
reset()
reset() 函數(shù)類似于新建一個(gè)路徑對(duì)象,除了填充類型 FillType 以外昏兆,Path 的所有數(shù)據(jù)都會(huì)被回收并重新分配枫虏。
-
rewind()
rewind() 函數(shù)會(huì)清除 FillType 和所有的路徑,保留內(nèi)部數(shù)據(jù)結(jié)構(gòu),以便更快地重用隶债。
比如我們需要重復(fù)繪制一類線段腾它,它們的點(diǎn)和數(shù)量相等,使用 rewind() 函數(shù)可以保留裝載點(diǎn)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)死讹,效率更高瞒滴。
要注意的是,只有重復(fù)繪制相同路徑時(shí)赞警,這些數(shù)據(jù)結(jié)構(gòu)才是可復(fù)用的妓忍。
2.6 雷達(dá)路徑
本節(jié)包含如下內(nèi)容。
- 創(chuàng)建畫(huà)筆
- 計(jì)算圓心
- 畫(huà)多邊形
- 畫(huà)網(wǎng)格線
- 畫(huà)數(shù)據(jù)圖
2.6.1 創(chuàng)建畫(huà)筆
[圖片上傳失敗...(image-af718b-1566988049043)]
2.6.2 計(jì)算圓心
在控件大小發(fā)生變化時(shí)仅颇,onSizeChanged() 會(huì)被回調(diào)并得到最新的控件大小,所以我們需要重寫這個(gè)方法碘举。
網(wǎng)狀路徑的大小占當(dāng)前控件的 90%忘瓦,所以半徑為:寬高最小值 ÷ 2 × 0.9。
然后根據(jù)中心點(diǎn)引颈,分別繪制雷達(dá)網(wǎng)格耕皮、網(wǎng)格中線、數(shù)據(jù)圖蝙场。
[圖片上傳失敗...(image-790871-1566988049043)]
2.6.3 畫(huà)多邊形
drawPolygon 涉及到三角函數(shù)凌停,下面是公式計(jì)算示意圖。
[圖片上傳失敗...(image-7650f6-1566988049043)]
下面是公式的具體實(shí)現(xiàn)售滤。
[圖片上傳失敗...(image-2b516d-1566988049043)]
2.6.4 畫(huà)網(wǎng)格線
[圖片上傳失敗...(image-8ff185-1566988049043)]
2.6.5 畫(huà)數(shù)據(jù)圖
[圖片上傳失敗...(image-2b881b-1566988049043)]
3. 文字繪制
本文包含如下內(nèi)容罚拟。
- 畫(huà)筆文字參數(shù)
- 畫(huà)布繪制文字
- 設(shè)置字體樣式
- 獲取文字寬高
3.1 畫(huà)筆文字參數(shù)
本節(jié)包含內(nèi)容如下。
- 文字參數(shù)
- 文字樣式
- 文字對(duì)齊
- 文字變形
- 其他設(shè)置
3.1.1 文字參數(shù)
下面是幾個(gè) Paint 中設(shè)置文字繪制效果的方法完箩。
[圖片上傳失敗...(image-474383-1566988049043)]
3.1.2 文字樣式
[圖片上傳失敗...(image-989051-1566988049043)]
3.1.2 文字對(duì)齊
我們可以通過(guò) Paint 的 setTextAlign(align) 方法來(lái)設(shè)置繪制文字時(shí)的對(duì)齊方向赐俗。
Paint 中有一個(gè)枚舉類 Align,在 Align 中定義了三種對(duì)齊模式:LEFT弊知、CENTER阻逮、RIGHT,這三種模式分別代表左對(duì)齊秩彤,居中對(duì)齊和右對(duì)齊叔扼。
[圖片上傳失敗...(image-62fdf1-1566988049043)]
3.1.4 文字變形
[圖片上傳失敗...(image-4209a-1566988049043)]
3.1.6 其他設(shè)置
[圖片上傳失敗...(image-8a030a-1566988049043)]
3.2 畫(huà)布繪制文字
上一節(jié)我們看到了Canvas 的 drawText() 方法,下面我們來(lái)看一下 Canvas 提供的其他繪制文本的方法漫雷。
本節(jié)包含內(nèi)容如下瓜富。
- 逐字繪制文字
- 路徑繪制文字
3.2.1 逐字繪制文字
[圖片上傳失敗...(image-3fbbdc-1566988049043)]
3.2.2 路徑繪制文字
在講解路徑繪制方向時(shí)我們就已經(jīng)用到過(guò) Canvas 提供了 drawTextOnPath() 方法,在這里我們看一下這個(gè)方法中的偏移參數(shù)降盹。
[圖片上傳失敗...(image-ae12ea-1566988049043)]
3.3 設(shè)置字體樣式
Paint 中提供了 setTypeFace(typeFace) 方法同于設(shè)置字體樣式食呻。
TypeFace 是專門用于設(shè)置字體樣式的,我們可以指定系統(tǒng)提供的字體也可以指定自定義字體。
當(dāng)創(chuàng)建 TypeFace 類時(shí)仅胞,可以指定是正常字體每辟、斜體或者粗體,當(dāng)指定樣式中沒(méi)有相關(guān)文字的樣式時(shí)干旧,就會(huì)用系統(tǒng)默認(rèn)的樣式顯示渠欺,一般默認(rèn)是宋體。
本節(jié)包含如下內(nèi)容椎眯。
- 系統(tǒng)字體
- 字體樣式
- 加載字體
3.3.1 系統(tǒng)字體
TypeFace 中提供了下面三種字體挠将,這三種字體對(duì)中文的支持不是很好,當(dāng)遇到不支持的文字時(shí)编整,會(huì)用系統(tǒng)默認(rèn)字體來(lái)寫舔稀。
[圖片上傳失敗...(image-79588b-1566988049043)]
下面是這三種字體的顯示效果。
[圖片上傳失敗...(image-ab18cf-1566988049043)]
3.3.2 字體樣式
除了可以選擇特定字體以外掌测,我們還可以通過(guò) defaultFromStyle() 方法選擇特定具體的某種樣式内贮。
TypeFace 中還定義了下面四種字體樣式。
[圖片上傳失敗...(image-763a48-1566988049043)]
下面是這四種樣式的顯示效果汞斧。
[圖片上傳失敗...(image-3ac806-1566988049043)]
3.3.3 加載字體
Android 提供了下面三種加載自定義字體的方式夜郁。
- 根據(jù)字體名加載
- 根據(jù)資源名加載
- 根據(jù)文件名加載
1. 根據(jù)字體名加載
TypeFace 中提供了一個(gè)用于根據(jù)字體名加載字體的 create() 方法,比如下面這行代碼這樣粘勒。
由于模擬器上沒(méi)有別的字體竞端,在這里就不演示了,大家有興趣的可以自己嘗試下庙睡。
[圖片上傳失敗...(image-db9163-1566988049043)]
2. 根據(jù)資源名加載
假如我們從網(wǎng)上下了個(gè) ttf 字體文件事富,想放在包中直接使用,我們可以在 app/src/main 目錄下建一個(gè) assets 目錄乘陪,再建一個(gè) fonts 目錄赵颅,然后把 ttf 文件放到里面。
而根據(jù)資源名加載字體的方式就是 TypeFace 的 createFromAsset() 方法暂刘。
[圖片上傳失敗...(image-b39454-1566988049043)]
3. 根據(jù)文件名加載字體
從資源中加載字體的弊端就是會(huì)讓 APK 包變大饺谬,如果我們把字體下載到本地的話就可以避免這個(gè)問(wèn)題。
[圖片上傳失敗...(image-f8a7db-1566988049043)]
3.4 獲取文字寬高
Paint 提供了三種獲取文字寬高的方法谣拣,下面我們來(lái)看一下這幾個(gè)方法的用法募寨。
本節(jié)內(nèi)容如下。
- 獲取字體寬度
- 獲取字體寬高
3.4.1 獲取字體寬度
[圖片上傳失敗...(image-134278-1566988049043)]
3.4.2 獲取字體寬高
[圖片上傳失敗...(image-fa0125-1566988049043)]
4. 區(qū)域操作
區(qū)域指的是 Region 類森缠,Region 是一塊任意形狀的封閉圖形拔鹰,這一節(jié)我們來(lái)看一下 Region 提供的一些操作區(qū)域的方法。
本節(jié)包含如下內(nèi)容。
- 創(chuàng)建區(qū)域
- 合并區(qū)域
- 裁剪區(qū)域
- 其他操作
4.1 創(chuàng)建區(qū)域
直接構(gòu)造區(qū)域指的是用 Region 的構(gòu)造函數(shù)創(chuàng)建區(qū)域,下面是 Region 的四個(gè)構(gòu)造函數(shù)工腋。
[圖片上傳失敗...(image-1e84ed-1566988049043)]
下面是一個(gè)繪制 Region 的簡(jiǎn)單示例勾哩,由于 Canvas 中沒(méi)有繪制 Region 的方法,所以我們?cè)谶@里自己定義一個(gè) drawRegion() 方法來(lái)繪制 Region糠涛。
Region 可用于繪制各種各樣的形狀贺拣,我們先看一下怎么繪制一個(gè)簡(jiǎn)單的正方形 Region鸦难。
[圖片上傳失敗...(image-da5147-1566988049043)]
4.2 合并區(qū)域
Region 提供了一個(gè) union(rect) 函數(shù)欧聘,傳入目標(biāo)矩陣到 union 函數(shù)中就能實(shí)現(xiàn)合并區(qū)域片林。
[圖片上傳失敗...(image-539c3-1566988049043)]
4.3 裁剪區(qū)域
Region 中聲明了下面的 5 個(gè)設(shè)置區(qū)域的方法。
[圖片上傳失敗...(image-e9cffc-1566988049043)]
裁剪區(qū)域需要先創(chuàng)建一個(gè)空 Region怀骤,然后調(diào)用 setPath 方法费封,下面是裁剪區(qū)域的操作,橢圓路徑和裁剪區(qū)域相交的區(qū)域就是裁剪結(jié)果蒋伦。
[圖片上傳失敗...(image-f9adb8-1566988049043)]
4.4 其他操作
本節(jié)如下內(nèi)容弓摘。
- 集合運(yùn)算方法
- 集合運(yùn)算類型
- 集合運(yùn)算示例
1. 集合運(yùn)算方法
除了 union 以外,Region 還提供了下面幾個(gè)區(qū)域操作方法痕届,而且 union 本身也是調(diào)用了 op 方法韧献。
[圖片上傳失敗...(image-8dfcea-1566988049043)]
2. 集合運(yùn)算類型
在上面這些方法中比較重要的是 Op 參數(shù),Op 是 Region 中定義的枚舉類爷抓,是集合運(yùn)算操作势决。
在這里阻塑,集合中的元素就是 Region 矩陣范圍中的子矩陣蓝撇。
[圖片上傳失敗...(image-2e85ed-1566988049043)]
**3. 集合運(yùn)算示例 **
下面是這些集合運(yùn)算的示例。
[圖片上傳失敗...(image-d1f254-1566988049043)]
5. 畫(huà)布
上一節(jié)我們講了怎么用畫(huà)布 Canvas 繪制各種圖形陈莽,畫(huà)布除了能用來(lái)繪制各種圖形以外渤昌,我們還能對(duì)畫(huà)筆進(jìn)行變換和裁剪。
本節(jié)內(nèi)容如下走搁。
- 畫(huà)布平移
- 畫(huà)布合成
- 畫(huà)布裁剪
- 畫(huà)布保存
4.1 畫(huà)布平移
畫(huà)布 Canvas 提供了一個(gè)可用于平移的方法 translate()独柑,畫(huà)布的原始狀態(tài)是以左上角為圓點(diǎn),向右是 X 軸正方向私植,向下是 Y 軸正方向忌栅。
由于畫(huà)布的左上角是坐標(biāo)軸的原點(diǎn)(0, 0),所以平移畫(huà)布后曲稼,坐標(biāo)系也會(huì)被平移索绪。
平移后的畫(huà)筆的左上角是新的坐標(biāo)原點(diǎn)。
[圖片上傳失敗...(image-34e63f-1566988049043)]
4.2 畫(huà)布合成
合成畫(huà)布與屏幕的操作是由系統(tǒng)進(jìn)行的贫悄,這一節(jié)我們來(lái)看一下這個(gè)操作的簡(jiǎn)單介紹瑞驱。
本節(jié)內(nèi)容如下。
- 合成
- 平移
- 小結(jié)
4.2.1 合成
我們每次在畫(huà)布上畫(huà)圖時(shí)窄坦,系統(tǒng)會(huì)先產(chǎn)生一個(gè)透明圖層唤反,在這個(gè)圖層上畫(huà)圖凳寺,花完后再覆蓋在屏幕上。
[圖片上傳失敗...(image-91e892-1566988049043)]
4.2.2 平移
當(dāng)我們繪制紅色矩形時(shí)彤侍,會(huì)產(chǎn)生另一個(gè)新的 Canvas 透明圖層肠缨,此時(shí)畫(huà)布坐標(biāo)改變了,所以繪圖方式如下圖所示拥刻。
由于 Canvas 已經(jīng)平移了 350 像素怜瞒,所以畫(huà)圖時(shí)是以新原點(diǎn)來(lái)產(chǎn)生視圖的,然后再合成到屏幕上般哼。
當(dāng)屏幕移動(dòng)后吴汪,有一部分超出屏幕的范圍,超出范圍的圖像是不顯示的蒸眠。
[圖片上傳失敗...(image-8fb2a4-1566988049043)]
4.2.3 小結(jié)
使用 Canvas 的繪制方法有下面三個(gè)需要注意的點(diǎn)漾橙。
-
生成新圖層
每次調(diào)用繪制方法 drawXXX 時(shí),都會(huì)產(chǎn)生一個(gè)新的 Canvas 透明圖層楞卡。
-
操作不可逆
調(diào)用了繪制方法前霜运,平移和旋轉(zhuǎn)等函數(shù)對(duì) Canvas 進(jìn)行了操作,那么這個(gè)操作是不可逆的蒋腮,每次產(chǎn)生的畫(huà)布的最新位置都是這些操作后的位置淘捡。
-
超出不顯示
在 Canvas 圖層與屏幕合成時(shí),超出屏幕范圍的圖像是不會(huì)顯示出來(lái)的
4.3 畫(huà)布裁剪
畫(huà)布裁剪是指用 Canvas 的 clipXXX 函數(shù)與矩形池摧、路徑和區(qū)域取交焦除、并、差等集合運(yùn)算來(lái)獲得最新的畫(huà)布形狀作彤。
除非使用了保存和恢復(fù)函數(shù)膘魄,否則裁剪操作是不可逆的,也就是一旦裁剪就無(wú)法恢復(fù)竭讳。
在 Canvas 中定義了下面幾個(gè)裁剪函數(shù)创葡。
[圖片上傳失敗...(image-634002-1566988049043)]
下面是一個(gè)裁剪示例。
[圖片上傳失敗...(image-88156e-1566988049043)]
4.4 畫(huà)布保存
在前面我們說(shuō)到了畫(huà)布的操作是不可逆的绢慢,這會(huì)造成很多麻煩灿渴。
比如為了實(shí)現(xiàn)一些效果需要對(duì)畫(huà)布進(jìn)行操作,但畫(huà)布狀態(tài)改變后又影響了后面的繪制效果胰舆。
因?yàn)檫@個(gè)原因骚露,畫(huà)布提供了保存和恢復(fù)功能,這兩個(gè)功能對(duì)應(yīng)的方法是 save() 和 restore()思瘟,每調(diào)用一次 save() 就會(huì)把當(dāng)前畫(huà)布狀態(tài)保存到棧中荸百。
本節(jié)內(nèi)容如下。
- 多次保存
- 指向恢復(fù)
- 圓形頭像
4.4.1 多次保存
畫(huà)布單次保存恢復(fù)的操作比較簡(jiǎn)單滨攻,我們來(lái)看一下畫(huà)布多次保存和多次恢復(fù)的效果够话。
[圖片上傳失敗...(image-e1ce9e-1566988049043)]
4.4.2 指向恢復(fù)
指向恢復(fù)指的是恢復(fù)到特定的狀態(tài)蓝翰,比如我們上面這個(gè)例子,假如我們要恢復(fù)到藍(lán)色400女嘲,那我們要調(diào)用三次 resoter()畜份。
為了解決這個(gè)問(wèn)題,Canvas 提供了另一個(gè)恢復(fù)畫(huà)布狀態(tài)的函數(shù) restoreToCount(count)欣尼,下面我們來(lái)看一下這個(gè)函數(shù)的用法爆雹。
[圖片上傳失敗...(image-62f1eb-1566988049043)]
4.4.3 圓形頭像
下面我們來(lái)看一下怎么用畫(huà)布的保存和恢復(fù)功能實(shí)現(xiàn)繪制圓形頭像后,再把畫(huà)布恢復(fù)回來(lái)愕鼓。
本節(jié)包含如下內(nèi)容钙态。
- 初始化
- 繪制頭像
- 去除鋸齒
1. 初始化
這里之所以要禁用硬件加速,是因?yàn)橛布铀偈鞘褂玫?OpenGL 函數(shù)完成實(shí)際繪制菇晃,而 OpenGL 并不能完全支持原始繪制函數(shù)册倒,比如 clipPath() 在開(kāi)啟硬件加速的情況下只有在 API 18 以上的系統(tǒng)才會(huì)生效。
[圖片上傳失敗...(image-a8b7d4-1566988049043)]
2. 繪制頭像
[圖片上傳失敗...(image-93fe0f-1566988049043)]
3. 去除鋸齒
clipPath 實(shí)現(xiàn)的圓形圖像是有鋸齒的磺送,我們可以用 PorterDuffXfermode 來(lái)實(shí)現(xiàn)無(wú)鋸齒的圓形圖片驻子。
[圖片上傳失敗...(image-f38436-1566988049043)]
. 代碼
https://github.com/zeshaoaaa/AndroidCustomView
作者:燈不利多
鏈接:https://juejin.im/post/5d61514df265da03d60f0ab6
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)估灿,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處崇呵。