如何通过Jetpack Compose实现双击点赞动画效果

2023-05-03,

这篇文章主要介绍如何通过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可以应用于

    • 缩放(scaleXscaleY

    • 旋转(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实现双击点赞动画效果.doc》

    下载本文的Word格式文档,以方便收藏与打印。