Crear animación de rebote táctil en Android Jetpack Compose

requisitos previos:

En este artículo, veremos cómo crear una animación de rebote cuando el usuario toca cualquier cosa, además, se puede extender según el uso de la aplicación. Aquí hay un gif de muestra que demuestra la animación.

Implementación paso a paso

Paso 1: cree un nuevo proyecto (o utilícelo en el proyecto Compose existente)

Para crear un nuevo proyecto en la versión Android Studio Canary, consulte el artículo Cómo crear un nuevo proyecto en la versión Android Studio Canary con Jetpack Compose.

Paso 2: trabajar con MainActivity.kt

Cree una clase de enumeración que almacene los estados (Liberado/Presionado).

Kotlin

enum class BounceState { Pressed, Released }

 
Paso 3: Agregar animación 

Cree una función componible Bounce, agregue el siguiente código 

Kotlin

var currentState: BounceState by remember { mutableStateOf(BounceState.Released) }
val transition = updateTransition(targetState = currentState, label = "animation")
 
val scale: Float by transition.animateFloat(
        transitionSpec = { spring(stiffness = 900f) }, label = ""
) { state ->
 
        // When the item is pressed , reduce
          // its size by 5% or make its size 0.95
          // of its original size
        // Change this value to see effect
        if (state == BounceState.Pressed) {
            0.95f
        } else {
            // When the item is released ,
              // make it of its original size
            1f
      }
}

Luego use el modificador pointerInputScope para detectar gestos y aplicar la animación, agregue el siguiente código al componible Bounce también. 

Kotlin

// Basic compose Box Layout
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column(modifier = Modifier
            .pointerInput(Unit) {
                detectTapGestures(onPress = {
 
                    // Set the currentState to Pressed
                      // to trigger Pressed animation
                    currentState = BounceState.Pressed
 
                    // Waits for the tap to release
                      // before returning the call
                    tryAwaitRelease()
 
                    // Set the currentState to Release
                      // to trigger Release animation
                    currentState = BounceState.Released
                })
            }) {
            Image(
                painter = painterResource(id = R.drawable.gfg),
                contentDescription = "gfg",
                modifier = Modifier.graphicsLayer {
                    scaleX = scale
                    scaleY = scale
              })
      }
}

 
Y hemos terminado. Este es el código final del archivo MainActivity.kt

Kotlin

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Image
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import com.shaun.bounceanimation.ui.theme.BounceAnimationTheme
 
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BounceAnimationTheme {
                Surface(color = MaterialTheme.colors.background) {
                    Bounce()
                }
            }
        }
    }
}
 
enum class BounceState { Pressed, Released }
 
@Preview(showBackground = true)
@Composable
fun Bounce() {
    var currentState: BounceState by remember { mutableStateOf(BounceState.Released) }
    val transition = updateTransition(targetState = currentState, label = "animation")
    val scale: Float by transition.animateFloat(
        transitionSpec = { spring(stiffness = 900f) }, label = ""
    ) { state ->
 
        // When the item is pressed ,reduce its size
          // by 5% or make its size 0.95 of its original size
        // Change this value to see effect
        if (state == BounceState.Pressed) {
            0.95f
        } else {
            // When the item is released ,
             // make it of its original size
            1f
        }
    }
 
// Basic compose Box Layout
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
 
Column(modifier = Modifier
            .pointerInput(Unit) {
                detectTapGestures(onPress = {
 
                    // Set the currentState to Pressed
                      // to trigger Pressed animation
                    currentState = BounceState.Pressed
 
                    // Waits for the tap to release
                      // before returning the call
                    tryAwaitRelease()
 
                    // Set the currentState to Release
                      // to trigger Release animation
                    currentState = BounceState.Released
                })
            }) {
            Image(
                painter = painterResource(id = R.drawable.gfg),
                contentDescription = "gfg",
                modifier = Modifier.graphicsLayer {
                    scaleX = scale
                    scaleY = scale
              })
        }
    }
}

Producción:

Obtenga el proyecto completo desde aquí .

Publicación traducida automáticamente

Artículo escrito por sunny52525 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *