通過Jetpack Compose實現雙擊點贊動畫效果
實現步驟
先紅色畫個愛心
Icon( Icons.Filled.Favorite, "愛心", Modifier .align(Alignment.Center) tint = Color.Red )
點擊事件加動畫
雙擊監聽
.pointerInput(Unit) { detectTapGestures( onDoubleTap = { ... } ) } #### **API 介紹** | API名稱 | 作用 | | --- | --- | | detectTapGestures | 監聽點擊手勢 | > 與 Clickable Modifier 不同的是,detectTapGestures 可以監聽更多的點擊事件。作為手機監聽的基礎 API,必然不會存在 Clickable Modifier 所拓展的漣漪效果 detectTapGestures 提供瞭四個可選參數 - onDoubleTap (可選):雙擊時回調 - onLongPress (可選):長按時回調 - onPress (可選):按下時回調 - onTap (可選):輕觸時回調 我們用到的就是`onDoubleTap`
用枚舉定義三個變量 開始、顯示和消失
enum class LikedStates { Initial, Liked, Disappeared }
remember保持數據狀態,mutableStateOf監聽狀態變化
var transitionState by remember { mutableStateOf(MutableTransitionState(LikedStates.Disappeared)) }
MutableTransitionState包含兩個字段:currentState和targetState。currentState初始化為提供的initialState,並且隻能通過轉換進行變異。targetState也初始化為initialState。可以對其進行變異,以改變使用updateTransition使用MutableTransitionState創建的過渡動畫的過程。currentState和targetState都由狀態對象支持。
判斷攔截數據變化過程,用於實現對應的動畫
if (transitionState.currentState == LikedStates.Initial) { transitionState.targetState = LikedStates.Liked } else if (transitionState.currentState == LikedStates.Liked) { transitionState.targetState = LikedStates.Disappeared }
開始顯示的過度動畫
val transition = updateTransition(transitionState = transitionState, label = null) val alpha by transition.animateFloat( transitionSpec = { ... } ) { if (it == LikedStates.Liked) 1f else 0f }
我們要實現有彈性的放大動畫,所以利用graphicsLayer實現縮放
graphicsLayer可以應用於
- 縮放(
scaleX
、scaleY
) - 旋轉(rotationX、rotationY、rotationZ)
- 不透明度(
alpha
) - 陰影(shadowElevation、shape)
- 剪裁(clip、shape)
定義scale,XY
1 :1放大所以定義一個就行
val scale by transition.animateFloat( transitionSpec = { .... } ) { ... }
創建浮動動畫作為給定變換的一部分targetValueByState
用作從目標狀態到此動畫的目標值的映射
最後在定義三種狀態裡嗎設置對應的參數
when (it) { LikedStates.Initial -> 0f LikedStates.Liked -> 4f LikedStates.Disappeared -> 2f }
完整代碼
@Suppress("TransitionPropertiesLabel") @Composable fun DoubleTapToLike() { var transitionState by remember { mutableStateOf(MutableTransitionState(LikedStates.Disappeared)) } Box( Modifier .fillMaxSize() .pointerInput(Unit) { detectTapGestures( onDoubleTap = { transitionState = MutableTransitionState(LikedStates.Initial) } ) } ) { if (transitionState.currentState == LikedStates.Initial) { transitionState.targetState = LikedStates.Liked } else if (transitionState.currentState == LikedStates.Liked) { transitionState.targetState = LikedStates.Disappeared } val transition = updateTransition(transitionState = transitionState, label = null) val alpha by transition.animateFloat( transitionSpec = { when { LikedStates.Initial isTransitioningTo LikedStates.Liked -> keyframes { durationMillis = 500 0f at 0 0.5f at 100 1f at 225 } LikedStates.Liked isTransitioningTo LikedStates.Disappeared -> tween(durationMillis = 200) else -> snap() } } ) { if (it == LikedStates.Liked) 1f else 0f } val scale by transition.animateFloat( transitionSpec = { when { LikedStates.Initial isTransitioningTo LikedStates.Liked -> spring(dampingRatio = Spring.DampingRatioHighBouncy) LikedStates.Liked isTransitioningTo LikedStates.Disappeared -> tween(200) else -> snap() } } ) { when (it) { LikedStates.Initial -> 0f LikedStates.Liked -> 4f LikedStates.Disappeared -> 2f } } Icon( Icons.Filled.Favorite, "點贊", Modifier .align(Alignment.Center) .graphicsLayer( alpha = alpha, scaleX = scale, scaleY = scale ), tint = Color.Red ) } } enum class LikedStates { Initial, Liked, Disappeared }
效果圖
到此這篇關於通過Jetpack Compose實現雙擊點贊動畫效果的文章就介紹到這瞭,更多相關Jetpack Compose內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Jetpack Compose實現動畫效果的方法詳解
- 利用Jetpack Compose繪制可愛的天氣動畫
- Jetpack Compose實現列表和動畫效果詳解
- Android開發Compose remember原理解析
- Android Jetpack結構運用Compose實現微博長按點贊彩虹效果