利用Jetpack?Compose實(shí)現(xiàn)繪制五角星效果
說明
compose中我們的所有ui操作,包括一些行為,例如:點(diǎn)擊、手勢(shì)等都需要使用Modifier來進(jìn)行操作。因此對(duì)Modifier的理解可以幫助我們解決很多問題的
自定義星行Modifier
本文我們打算自定義一個(gè)Modifier,通過這個(gè)modifier我們可以實(shí)現(xiàn)用一個(gè)操作符就畫出五角星的效果
原理
我們實(shí)現(xiàn)繪制五角星的原理如下圖,首先我們會(huì)虛構(gòu)兩個(gè)圓,將內(nèi)圓和外圓角度平分五份,然后依次連接內(nèi)圓和外圓的切點(diǎn)的坐標(biāo),然后使用path繪制完成。

實(shí)現(xiàn)
代碼中的實(shí)現(xiàn)涉及到自定義繪制,難度并不大。需要注意的點(diǎn):
- composse中角度的錨點(diǎn)是弧度(Math.PI)、而原生的錨點(diǎn)是角度(360)
- 默認(rèn)的原點(diǎn)在左上角,我們繪制的時(shí)候需要主動(dòng)移動(dòng)到組合的中心點(diǎn)
- path的繪制使用Fill可以填充閉合路徑圖形,使用Stroke可以繪制線性閉合路徑圖形
代碼
fun Modifier.customDraw(
color: Color,
starCount: Int = 5,
checked: Boolean = false,
) =
this.then(CustomDrawModifier(color, starCount, checked = checked))
class CustomDrawModifier(
private val color: Color,
private val starCount: Int = 5,//星的數(shù)量
private var checked: Boolean = false,
) :
DrawModifier {
override fun ContentDrawScope.draw() {
log("$size")
val radiusOuter = if (size.width > size.height) size.height / 2 else size.width / 2 //五角星外圓徑
val radiusInner = radiusOuter / 2 //五角星內(nèi)圓半徑
val startAngle = (-Math.PI / 2).toFloat() //開始繪制點(diǎn)的外徑角度
val perAngle = (2 * Math.PI / starCount).toFloat() //兩個(gè)五角星兩個(gè)角直接的角度差
val outAngles = (0 until starCount).map {
val angle = it * perAngle + startAngle
Offset(radiusOuter * cos(angle), radiusOuter * sin(angle))
}//所有外圓角的頂點(diǎn)
val innerAngles = (0 until starCount).map {
val angle = it * perAngle + perAngle / 2 + startAngle
Offset(radiusInner * cos(angle), radiusInner * sin(angle))
}//所有內(nèi)圓角的頂點(diǎn)
val path = Path()//繪制五角星的所有內(nèi)圓外圓的點(diǎn)連接線
(0 until starCount).forEachIndexed { index, _ ->
val outerX = outAngles[index].x
val outerY = outAngles[index].y
val innerX = innerAngles[index].x
val innerY = innerAngles[index].y
// drawCircle(Color.Red, radius = 3f, center = outAngles[index])
// drawCircle(Color.Yellow, radius = 3f, center = innerAngles[index])
if (index == 0) {
path.moveTo(outerX, outerY)
path.lineTo(innerX, innerY)
path.lineTo(outAngles[(index + 1) % starCount].x,
outAngles[(index + 1) % starCount].y)
} else {
path.lineTo(innerX, innerY)//移動(dòng)到內(nèi)圓角的端點(diǎn)
path.lineTo(outAngles[(index + 1) % starCount].x,
outAngles[(index + 1) % starCount].y)//連接到下一個(gè)外圓角的端點(diǎn)
}
if (index == starCount - 1) {
path.close()
}
}
translate(size.width / 2, size.height / 2) {
drawPath(path, color, style = if (checked) Fill else Stroke(width = 5f))
}
}
}
最終實(shí)現(xiàn)效果

以上就是利用Jetpack Compose實(shí)現(xiàn)繪制五角星效果的詳細(xì)內(nèi)容,更多關(guān)于Jetpack Compose五角星的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android FaceDetector實(shí)現(xiàn)人臉檢測(cè)功能
這篇文章主要為大家詳細(xì)介紹了Android FaceDetector實(shí)現(xiàn)人臉檢測(cè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android實(shí)現(xiàn)價(jià)格走勢(shì)自定義曲線圖
本篇文章主要介紹了Android實(shí)現(xiàn)價(jià)格走勢(shì)曲線圖,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04
AsyncTask陷阱之:Handler,Looper與MessageQueue的詳解
本篇文章是對(duì)Handler,Looper與MessageQueue進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android中TextView顯示圓圈背景或設(shè)置圓角的方法
TextView顯示文本給用戶,并允許他們選擇編輯。TextView是一個(gè)完整的文本編輯器,但是其基本類配置為不允許編輯。下面這篇文章主要給大家介紹了關(guān)于Android中TextView顯示圓圈背景或設(shè)置圓角的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-05-05
Android開發(fā)使用UncaughtExceptionHandler捕獲全局異常
本文主要介紹在Android開發(fā)中使用UncaughtExceptionHandler捕獲全局異常,需要的朋友可以參考下。2016-06-06
Android自定義View實(shí)現(xiàn)廣告信息上下滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)廣告信息上下滾動(dòng)的具體代碼,感興趣的小伙伴們可以參考一下2016-05-05

