“This is the fourth day of my participation in the First Challenge 2022

Let me draw it in red ❤

Icon(
    Icons.Filled.Favorite,
    "Love",
    Modifier
        .align(Alignment.Center)    
    tint = Color.Red
)
Copy the code

Then it’s click events plus animations

Double-click on the monitor

.pointerInput(Unit) { detectTapGestures( onDoubleTap = { ... })} # # # # API introduces * * * * | API names function | | | -- - | -- - | | detectTapGestures | | click gestures > with Clickable Modifier, DetectTapGestures can listen for more click events. DetectTapGestures offers four optional parameters - onDoubleTap (optional) : Double click callback - onLongPress (optional) : long time callback - onPress (optional) : tap callback - onTap (optional) : tap callback we use is' onDoubleTap 'Copy the code

Use enumeration to define three variables to start, show, and disappear

enum class LikedStates {
    Initial,
    Liked,
    Disappeared
}
Copy the code

Remember to keep data state, mutableStateOf listens for state changes

var transitionState by remember {
    mutableStateOf(MutableTransitionState(LikedStates.Disappeared))
}
Copy the code

MutableTransitionState contains two fields: currentState and targetState. CurrentState is initialized to the provided initialState and can only be mutated by transformation. TargetState is also initialized to initialState. You can mutate it to change the process of animation transitions created using updateTransition using MutableTransitionState. Both currentState and targetState are supported by state objects.

Judge the process of intercepting data changes and use it to realize the corresponding animation

if (transitionState.currentState == LikedStates.Initial) {
    transitionState.targetState = LikedStates.Liked
} else if (transitionState.currentState == LikedStates.Liked) {
    transitionState.targetState = LikedStates.Disappeared
}
Copy the code

Begin to display the transition animation

val transition = updateTransition(transitionState = transitionState, label = null)
val alpha bytransition.animateFloat( transitionSpec = { ... {})if (it == LikedStates.Liked) 1f else 0f
}
Copy the code

We want to do elastic zooming animation, so we use graphicsLayer for zooming

GraphicsLayer can be applied to Scale (scaleX, scaleY) rotationX, rotationY, rotationZ) Opacity (Alpha) shadowElevation (Shape) Clip, shape.

Define scale, XY

1:1 zoom in so just define one

val scale bytransition.animateFloat( transitionSpec = { .... {...}) }Copy the code

Create a floating animation as part of the given transformation targetValueByState is used as a mapping from the target state to the target value of this animation

Finally, set the corresponding parameters in the definition of the three states

 when (it) {
        LikedStates.Initial -> 0f
        LikedStates.Liked -> 4f
        LikedStates.Disappeared -> 2f
    }
Copy the code

knowledge

The complete code

@Suppress("TransitionPropertiesLabel")
@Composable
 fun DoubleTapToLike(a) {
    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.5 f 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,
            "Thumb up",
            Modifier
                .align(Alignment.Center)
                .graphicsLayer(
                    alpha = alpha,
                    scaleX = scale,
                    scaleY = scale
                ),
            tint = Color.Red
        )
    }
}
enum class LikedStates {
    Initial,
    Liked,
    Disappeared
}
Copy the code

rendering