使用Compose制作抖音快手視頻進(jìn)度條Loading動(dòng)畫(huà)效果
引言
現(xiàn)在互聯(lián)網(wǎng)產(chǎn)品,感覺(jué)誰(shuí)家的App不整點(diǎn)視頻功能,嚴(yán)格意義上都不能說(shuō)是一個(gè)現(xiàn)代互聯(lián)網(wǎng)App了??,我們知道最火的是抖音、快手這類短視頻App,在刷視頻的同時(shí),他們的App交互上面的一些特色能讓我們一直沉浸在刷視頻中;
比如,我們今天要聊的,短視頻翻頁(yè)流列表,視頻加載緩沖的時(shí)候,Loading的設(shè)計(jì):
它設(shè)計(jì):在視頻底部,進(jìn)度條上面,當(dāng)視頻緩沖加載等待的時(shí)候,它有一個(gè)波紋的擴(kuò)散效果,
即不干擾用戶刷視頻的操作,也沒(méi)有很明顯的突兀效果
(比如:突兀的屏幕中間大圓圈Loading,就很突兀)
Loading效果
我們先來(lái)看一下“抖音、快手App”的視頻進(jìn)度條Loading效果(GIF圖稍微失真了點(diǎn))
快手短視頻首頁(yè)的視頻Loading
從視頻里面可以看出來(lái)在視頻底部,出現(xiàn)緩沖加載視頻的時(shí)候,會(huì)有一個(gè):“從中間往2邊擴(kuò)散”的效果。
GIF圖放慢了一點(diǎn),方便大家觀看,實(shí)際研究過(guò)程,我一般是通過(guò)錄制完視頻,通過(guò)相冊(cè)的視頻編輯,去一幀一幀看,做了哪些動(dòng)作,如下:
看完,我們發(fā)現(xiàn):
1、一開(kāi)始是在屏幕中間的位置,大概是20dp左右的寬度開(kāi)始顯示;
2、從中間擴(kuò)散到屏幕邊緣之后,會(huì)執(zhí)行漸隱;
3、漸隱到透明,又開(kāi)始從中間往2邊擴(kuò)散;
BoxWithConstraints代碼
有了上面的前奏,我們就可以開(kāi)始我們的編碼了,那么在開(kāi)始編碼前,肯定需要知道寬度是多少,這里我們拿BoxWithConstraints來(lái)包我們的child composable, 我們可以看到BoxWithConstraints的代碼如下:
// 代碼來(lái)自:androidx.compose.foundation.layout @Composable @UiComposable fun BoxWithConstraints( modifier: Modifier = Modifier, contentAlignment: Alignment = Alignment.TopStart, propagateMinConstraints: Boolean = false, content: @Composable @UiComposable BoxWithConstraintsScope.() -> Unit ) { val measurePolicy = rememberBoxMeasurePolicy(contentAlignment, propagateMinConstraints) SubcomposeLayout(modifier) { constraints -> val scope = BoxWithConstraintsScopeImpl(this, constraints) val measurables = subcompose(Unit) { scope.content() } with(measurePolicy) { measure(measurables, constraints) } } }
里面用到了SubcomposeLayout,來(lái)推遲內(nèi)容組合,我們可以在BoxWithConstraintsScope里面獲取到最大寬度maxWidth (單位dp)。
Loading線條,我們可以用DrawScope.drawLine來(lái)畫(huà),擴(kuò)散效果肯定需要有動(dòng)畫(huà)來(lái)更新。
animateFloat獲取動(dòng)畫(huà)更新值
我們使用 rememberInfiniteTransition() 執(zhí)行無(wú)限動(dòng)畫(huà),使用animateFloat來(lái)獲取動(dòng)畫(huà)更新的值:
// 代碼來(lái)自:androidx.compose.animation.core @Composable fun InfiniteTransition.animateFloat( initialValue: Float, targetValue: Float, animationSpec: InfiniteRepeatableSpec<Float> ): State<Float>
初始值(initialValue)可以定義成50F(讀者可自行修改),目標(biāo)值(targetValue)定義多少合適呢?
通過(guò)慢鏡頭查看“抖音、快手”的效果,發(fā)現(xiàn)它擴(kuò)散完,會(huì)“漸隱到透明”,然后再?gòu)?strong>intialValue處開(kāi)始重新擴(kuò)散。
targetValue定義成maxWidth不行,那么我們拉大這個(gè)數(shù)值,可以定義成大概1.8倍的maxWidth;
由于maxWidth獲取到的是dp單位的,我們需要轉(zhuǎn)換成px,下面我們統(tǒng)一叫:width
val width = with(LocalDensity.current) { maxWidth.toPx() }
線條動(dòng)畫(huà)值
然后,我們的線條動(dòng)畫(huà)值就變成下面這樣:
val lineProgressAnimValue by infiniteTransition.animateFloat( initialValue = 100F, targetValue = width * 1.8F, animationSpec = infiniteRepeatable( animation = tween( durationMillis = TIME_PERIOD, easing = FastOutLinearInEasing ) ) ) private const val TIME_PERIOD = 1100
執(zhí)行漸隱
線條擴(kuò)散到屏幕邊緣的時(shí)候,需要執(zhí)行漸隱,得出下面的alpha
val lineAlphaValue = if(lineProgressAnimValue <= width) { // 讀者可以根據(jù)自己體驗(yàn) lineProgressAnimValue * 1.0F/ width * 1.0F // 讀者可以根據(jù)自己體驗(yàn) //Math.min((lineProgressAnimValue.value) * 1.0F / width * 1.0F, 0.7F) // 抖音、快手看效果都是1F,根據(jù)自己體驗(yàn)來(lái)設(shè)置吧 // 1F } else { // 擴(kuò)散到屏幕邊緣的時(shí)候,開(kāi)始觸發(fā):漸隱 (width * 1.8F - lineProgressAnimValue) / width * 0.8F } // 線條寬度 val lineWidth = if(lineProgressAnimValue <= width) { lineProgressAnimValue / 2 } else { width / 2 }
最后,我們通過(guò)Canvas來(lái)繪制這個(gè)線條
Canvas(modifier = modifier) { drawLine( color = Color.White.copy(alpha = lineAlphaValue), start = Offset(x = size.width / 2 - lineWidth, y = 0F), end = Offset(x = size.width / 2 + lineWidth, y = 0F), strokeWidth = 2.5F ) }
最終效果
以上就是使用Compose制作抖音快手視頻進(jìn)度條Loading動(dòng)畫(huà)效果的詳細(xì)內(nèi)容,更多關(guān)于Compose視頻進(jìn)度條Loading的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Compose開(kāi)發(fā)之動(dòng)畫(huà)藝術(shù)探索及實(shí)現(xiàn)示例
- Jetpack Compose實(shí)現(xiàn)列表和動(dòng)畫(huà)效果詳解
- Jetpack Compose實(shí)現(xiàn)動(dòng)畫(huà)效果的方法詳解
- 通過(guò)Jetpack Compose實(shí)現(xiàn)雙擊點(diǎn)贊動(dòng)畫(huà)效果
- 利用Jetpack Compose繪制可愛(ài)的天氣動(dòng)畫(huà)
- Compose?動(dòng)畫(huà)藝術(shù)探索之可見(jiàn)性動(dòng)畫(huà)示例詳解
相關(guān)文章
android基礎(chǔ)教程之開(kāi)機(jī)啟動(dòng)示例
這篇文章主要介紹了android開(kāi)機(jī)啟動(dòng)示例,開(kāi)機(jī)自動(dòng)啟動(dòng)程序后開(kāi)機(jī)啟動(dòng)廣播功能實(shí)現(xiàn),需要的朋友可以參考下2014-02-02Android?O對(duì)后臺(tái)Service限制詳解
這篇文章主要為大家介紹了Android?O對(duì)后臺(tái)Service限制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android中Market的Loading效果實(shí)現(xiàn)方法
這篇文章主要介紹了Android中Market的Loading效果實(shí)現(xiàn)方法,較為詳細(xì)的分析了Android中l(wèi)oading效果的相關(guān)布局及功能實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Jetpack?Compose慣性衰減動(dòng)畫(huà)AnimateDecay詳解
這篇文章主要為大家介紹了Jetpack?Compose慣性衰減動(dòng)畫(huà)AnimateDecay詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11詳解Android中的MVP架構(gòu)分解和實(shí)現(xiàn)
本篇文章主要介紹了詳解Android中的MVP架構(gòu)分解和實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02Android入門之使用SimpleAdapter實(shí)現(xiàn)復(fù)雜界面布局
這篇文章主要為大家詳細(xì)介紹了Android如何使用SimpleAdapter實(shí)現(xiàn)復(fù)雜的界面布局,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Android有一定的幫助,需要的可以參考一下2022-11-11Android自定義View實(shí)現(xiàn)圓環(huán)進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)圓環(huán)進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05