Compose自定義View實(shí)現(xiàn)宇智波斑寫輪眼
正文
本章節(jié)是Compose自定義繪制的第二章,畫的是一個(gè)之前設(shè)計(jì)給的一個(gè)比較復(fù)雜的,設(shè)計(jì)所謂的會(huì)呼吸的動(dòng)畫,那時(shí)候?qū)崿F(xiàn)花了蠻長的時(shí)間,搬著電腦跟設(shè)計(jì)一幀一幀地對,沒多久后來需求就被拿掉了,至于文章的標(biāo)題哈哈隨意起了一個(gè),長得有點(diǎn)像而已。
Compose的實(shí)現(xiàn),圖形本身跟上一章節(jié)的LocationMarker其實(shí)差不太多,倒過來了而已,調(diào)整了P1跟P3, 基本圖形的Path,這里不再做介紹,讀者也可以去看代碼實(shí)現(xiàn)。主要介紹一下動(dòng)畫吧。
首先看一下gif動(dòng)圖:
整個(gè)圖形分三層,最底層是灰色的背景,沒有動(dòng)畫實(shí)現(xiàn)。
先實(shí)現(xiàn)功能效果
第二層是一個(gè)層變的動(dòng)畫,每層有個(gè)delay的不同延遲,對alpha最一個(gè)ObjectAnimator.ofFloat(water1, "alpha", 0f, 0.5f, 0.2f, 1f)漸變的動(dòng)畫,0.5f 到0.2f, 再到1f這個(gè)地方展現(xiàn)出所謂的呼吸的感覺。Compose目前寫的不多,有些冗余代碼沒有抽象,先實(shí)現(xiàn)了功能效果。
@Composable fun drawWaterDrop(){ val waterDropModel by remember { mutableStateOf(WaterDropModel.waterDropM) } val color1 = colorResource(id = waterDropModel.water1.colorResource) val color2 = colorResource(id = waterDropModel.water2.colorResource) val color3 = colorResource(id = waterDropModel.water3.colorResource) val color4 = colorResource(id = waterDropModel.water4.colorResource) val color5 = colorResource(id = waterDropModel.water5.colorResource) val color6 = colorResource(id = waterDropModel.water6.colorResource) val color7 = colorResource(id = waterDropModel.water7.colorResource) val color8 = colorResource(id = waterDropModel.water8.colorResource) val animAlpha1 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha2 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha3 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha4 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha5 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha6 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha7 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha8 = remember { Animatable(0f, Float.VectorConverter) } LaunchedEffect(Unit){ animAlpha1.animateTo(1f, animationSpec = myKeyframs(0)) } LaunchedEffect(Unit){ animAlpha2.animateTo(1f, animationSpec = myKeyframs(1)) } LaunchedEffect(Unit){ animAlpha3.animateTo(1f, animationSpec = myKeyframs(2)) } LaunchedEffect(Unit){ animAlpha4.animateTo(1f, animationSpec = myKeyframs(3)) } LaunchedEffect(Unit){ animAlpha5.animateTo(1f, animationSpec = myKeyframs(4)) } LaunchedEffect(Unit){ animAlpha6.animateTo(1f, animationSpec = myKeyframs(5)) } LaunchedEffect(Unit){ animAlpha7.animateTo(1f, animationSpec = myKeyframs(6)) } LaunchedEffect(Unit){ animAlpha8.animateTo(1f, animationSpec = myKeyframs(7)) } Canvas(modifier = Modifier.fillMaxSize()){ val contentWidth = size.width val contentHeight = size.height withTransform({ translate(left = contentWidth / 2, top = contentHeight / 2)}) { drawPath(AndroidPath(waterDropModel.water8Path), color = color8, alpha = animAlpha8.value) drawPath(AndroidPath(waterDropModel.water7Path), color = color7, alpha = animAlpha7.value) drawPath(AndroidPath(waterDropModel.water6Path), color = color6, alpha = animAlpha6.value) drawPath(AndroidPath(waterDropModel.water5Path), color = color5, alpha = animAlpha5.value) drawPath(AndroidPath(waterDropModel.water4Path), color = color4, alpha = animAlpha4.value) drawPath(AndroidPath(waterDropModel.water3Path), color = color3, alpha = animAlpha3.value) drawPath(AndroidPath(waterDropModel.water2Path), color = color2, alpha = animAlpha2.value) drawPath(AndroidPath(waterDropModel.water1Path), color = color1, alpha = animAlpha1.value) } } } private fun myKeyframs(num:Int):KeyframesSpec<Float>{ return keyframes{ durationMillis = 3000 delayMillis = num * 2000 0.5f at 1000 with LinearEasing 0.2f at 2000 with LinearEasing } }
調(diào)用傳入不同的delay值
然后就是外層掃光的動(dòng)畫,像探照燈一樣一圈圈的掃,一共掃7遍,代碼跟層變動(dòng)畫差不多,也是對alpha值做漸變,目前代碼是調(diào)用掃光動(dòng)畫7次,后續(xù)看看如何優(yōu)化性能。每次調(diào)用傳入不同的delay值即可。
@Composable fun drawWaterDropScan(delayTime:Long){ val waterDropModel by remember { mutableStateOf(WaterDropModel.waterDropMScan) } val color1 = colorResource(id = waterDropModel.water1.colorResource) val color2 = colorResource(id = waterDropModel.water2.colorResource) val color3 = colorResource(id = waterDropModel.water3.colorResource) val color4 = colorResource(id = waterDropModel.water4.colorResource) val color5 = colorResource(id = waterDropModel.water5.colorResource) val color6 = colorResource(id = waterDropModel.water6.colorResource) val color7 = colorResource(id = waterDropModel.water7.colorResource) val color8 = colorResource(id = waterDropModel.water8.colorResource) val animAlpha2 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha3 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha4 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha5 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha6 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha7 = remember { Animatable(0f, Float.VectorConverter) } val animAlpha8 = remember { Animatable(0f, Float.VectorConverter) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(1f, 350) } animAlpha2.animateTo(0f, animationSpec = myKeyframs2(700, 0, map)) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(0.8f, 315) } animAlpha3.animateTo(0f, animationSpec = myKeyframs2(630, 233, map)) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(0.55f, 315) } animAlpha4.animateTo(0f, animationSpec = myKeyframs2(630, 383, map)) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(0.5f, 325) } animAlpha5.animateTo(0f, animationSpec = myKeyframs2(650, 533, map)) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(0.45f, 325) } animAlpha6.animateTo(0f, animationSpec = myKeyframs2(650, 667, map)) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(0.35f, 283) } animAlpha7.animateTo(0f, animationSpec = myKeyframs2(567, 816, map)) } LaunchedEffect(Unit){ delay(delayTime) val map = mutableMapOf<Float, Int>().apply { put(0.3f, 216) } animAlpha8.animateTo(0f, animationSpec = myKeyframs2(433, 983, map)) } Canvas(modifier = Modifier.fillMaxSize()){ val contentWidth = size.width val contentHeight = size.height withTransform({ translate(left = contentWidth / 2, top = contentHeight / 2) }) { drawPath(AndroidPath(waterDropModel.water8Path), color = color8, alpha = animAlpha8.value) drawPath(AndroidPath(waterDropModel.water7Path), color = color7, alpha = animAlpha7.value) drawPath(AndroidPath(waterDropModel.water6Path), color = color6, alpha = animAlpha6.value) drawPath(AndroidPath(waterDropModel.water5Path), color = color5, alpha = animAlpha5.value) drawPath(AndroidPath(waterDropModel.water4Path), color = color4, alpha = animAlpha4.value) drawPath(AndroidPath(waterDropModel.water3Path), color = color3, alpha = animAlpha3.value) drawPath(AndroidPath(waterDropModel.water2Path), color = color2, alpha = animAlpha2.value) drawPath(AndroidPath(waterDropModel.water1Path), color = color1) } } } private fun myKeyframs2(durationMillisParams:Int, delayMillisParams:Int, frames:Map<Float, Int>):KeyframesSpec<Float>{ return keyframes{ durationMillis = durationMillisParams delayMillis = delayMillisParams for ((valueF, timestamp) in frames){ valueF at timestamp } } } @Preview @Composable fun WaterDrop(){ Box(modifier = Modifier.fillMaxSize()){ drawWaterDropBg() drawWaterDrop() for (num in 1 .. 7){ drawWaterDropScan(delayTime = num * 2000L) } } }
代碼跟LocationMarker在一個(gè)Project里面,暫時(shí)沒有添加導(dǎo)航。github.com/yinxiucheng… 下的CustomerComposeView.
以上就是Compose自定義View實(shí)現(xiàn)宇智波斑寫輪眼的詳細(xì)內(nèi)容,更多關(guān)于Compose自定義View的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android刮刮樂效果-proterDuffXfermode的示例代碼
這篇文章主要介紹了Android刮刮樂效果-proterDuffXfermode,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12ListView點(diǎn)擊Item展開菜單實(shí)現(xiàn)代碼詳解
這篇文章主要介紹了ListView點(diǎn)擊Item展開菜單實(shí)現(xiàn)代碼詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06Android中實(shí)現(xiàn)根據(jù)資源名獲取資源ID
這篇文章主要介紹了Android中實(shí)現(xiàn)根據(jù)資源名獲取資源ID,本文講解了使用文件名獲取資源ID的方法,需要的朋友可以參考下2015-01-01Android 正則表達(dá)式驗(yàn)證手機(jī)號、姓名(包含少數(shù)民族)、身份證號
本篇文章主要介紹了Android 正則表達(dá)式驗(yàn)證手機(jī)號、姓名(包含少數(shù)民族)、身份證號的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04Android 點(diǎn)擊ImageButton時(shí)有“按下”的效果的實(shí)現(xiàn)
這篇文章主要介紹了 Android 點(diǎn)擊ImageButton時(shí)有“按下”的效果的實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-03-03Android實(shí)現(xiàn)復(fù)制Assets文件到SD卡
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)復(fù)制Assets文件到SD卡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12360瀏覽器文本框獲得焦點(diǎn)后被android軟鍵盤遮罩該怎么辦
最近接了個(gè)項(xiàng)目,項(xiàng)目需求是這樣的,站點(diǎn)上篩選按鈕點(diǎn)擊后彈出層(fixed),當(dāng)輸入框獲取焦點(diǎn)以后彈出系統(tǒng)自帶的軟鍵盤,在android上十款瀏覽器挨個(gè)測試比對,發(fā)現(xiàn)在360瀏覽器彈出鍵盤以后獲取焦點(diǎn)的文本框被軟鍵盤覆蓋了,下面分享我的解決辦法2015-12-12