In this article, we will take a look at how to create a bounce animation when the user taps anything, further it can be extended as per the use of the App.
Prerequisites:
- Basic knowledge of Kotlin
- Basic Knowledge of Jetpack Compose
Step by Step Implementation
Step 1: Create a New Project
To create a new project in the Android Studio, please refer to How to Create a new Project in Android Studio with Jetpack Compose.
Note: Select Kotlin as the programming language.
Step 2: Working with the MainActivity.kt
Create an enum class that stores the states (Released / Pressed).
enum class BounceState { Pressed, Released }MainActivity.kt:
package com.geeksforgeeks.demo
import android.os.Bundle
import androidx.activity.*
import androidx.activity.compose.setContent
import androidx.compose.animation.core.*
import androidx.compose.foundation.Image
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
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 androidx.compose.ui.unit.dp
import com.geeksforgeeks.demo.ui.theme.DemoTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
DemoTheme(dynamicColor = false, darkTheme = false) {
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 ->
if (state == BounceState.Pressed) {
// reduce size by 20% on press
0.8f
} else {
// return to original on release
1f
}
}
// create ui for image
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_logo),
contentDescription = "gfg",
modifier = Modifier
.graphicsLayer {
scaleX = scale
scaleY = scale
}
.size(200.dp)
)
}
}
}