利用Jetpack?Compose實(shí)現(xiàn)繪制五角星效果
說明
compose中我們的所有ui操作,包括一些行為,例如:點(diǎn)擊、手勢等都需要使用Modifier來進(jìn)行操作。因此對Modifier的理解可以幫助我們解決很多問題的
自定義星行Modifier
本文我們打算自定義一個Modifier,通過這個modifier我們可以實(shí)現(xiàn)用一個操作符就畫出五角星的效果
原理
我們實(shí)現(xiàn)繪制五角星的原理如下圖,首先我們會虛構(gòu)兩個圓,將內(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)在左上角,我們繪制的時候需要主動移動到組合的中心點(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() //兩個五角星兩個角直接的角度差 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)//移動到內(nèi)圓角的端點(diǎn) path.lineTo(outAngles[(index + 1) % starCount].x, outAngles[(index + 1) % starCount].y)//連接到下一個外圓角的端點(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五角星的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Crashlytics Android 異常報告統(tǒng)計管理(詳解)
下面小編就為大家?guī)硪黄狢rashlytics Android 異常報告統(tǒng)計管理(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05Android小程序?qū)崿F(xiàn)訪問聯(lián)系人
這篇文章主要為大家詳細(xì)介紹了Android小程序?qū)崿F(xiàn)訪問聯(lián)系人,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一2020-05-05Android實(shí)現(xiàn)頁面翻轉(zhuǎn)和自動翻轉(zhuǎn)功能
這篇文章主要介紹了Android中簡單實(shí)現(xiàn)頁面翻轉(zhuǎn)和自動翻轉(zhuǎn)的功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-10-10Android7.0指紋服務(wù)FingerprintService實(shí)例介紹
這篇文章主要介紹了Android7.0指紋服務(wù)FingerprintService介紹,需要的朋友可以參考下2018-01-01viewPager+fragment刷新緩存fragment的方法
這篇文章主要介紹了viewPager+fragment刷新緩存fragment的方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03Android實(shí)現(xiàn)聯(lián)動下拉框二級地市聯(lián)動下拉框功能
這篇文章主要介紹了Android實(shí)現(xiàn)聯(lián)動下拉框二級地市聯(lián)動下拉框功能,本文給大家分享思路步驟,給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2018-12-12Jetpack?Compose對比React?Hooks?API相似度
這篇文章主要為大家介紹了Jetpack?Compose對比React?Hooks?API相似度,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08