Test

Bring Your UI to Life with Lottie Animations in Jetpack Compose

Want to add engaging animations to your app? Lottie animations are the way to go! They bring smooth, scalable animations to your UI with minimal effort. In Jetpack Compose, integrating Lottie is simple using the LottieAnimation composable. Below, we’ll show you how to use Lottie animations with interactive controls like play, pause, speed, scale, rotation, and more.

Lottie Animation Example

Quick Peek: What You'll See Here

We’ll use a Lottie animation with success, failure, and looping states, controlled by buttons for play/pause, speed, scale, rotation, and opacity. Each example includes code you can copy and explanations of why it works. Let’s dive in!

1. Basic Lottie Animation Setup

Load a Lottie animation from a raw resource and display it with default settings. This is the foundation for all Lottie animations in Compose.


@Composable
fun BasicLottieAnimation() {
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    LottieAnimation(
        composition = composition,
        progress = { animateLottieCompositionAsState(composition).value },
        modifier = Modifier.size(320.dp).padding(16.dp)
    )
}
        
        
        

Why Try It: Uses rememberLottieComposition to load the animation and LottieAnimation to display it. Perfect for simple animations like loading spinners.


2. Interactive Animation Controls

Add buttons to control play/pause, success, and failure states, with custom animation ranges for each state.


@Composable
fun InteractiveLottieAnimation() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val progress by animateLottieCompositionAsState(
        composition = composition,
        iterations = if (lottieState.isSuccess || lottieState.isFailed) 1 else LottieConstants.IterateForever,
        isPlaying = lottieState.isPlaying,
        clipSpec = LottieClipSpec.Progress(
            min = if (lottieState.isFailed) 0.499f else 0.0f,
            max = when {
                lottieState.isSuccess -> 0.44f
                lottieState.isFailed -> 0.95f
                else -> 0.282f
            }
        )
    )
    Column(
        modifier = Modifier.fillMaxSize().background(Color.White),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        LottieAnimation(
            composition = composition,
            progress = { progress },
            modifier = Modifier.size(320.dp).padding(16.dp)
        )
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Play Full", Icons.Default.PlayArrow) {
                lottieState = lottieState.copy(isPlaying = true, isSuccess = false, isFailed = false)
            }
            SimpleButton("Success", Icons.Default.Check) {
                lottieState = lottieState.copy(isPlaying = true, isSuccess = true, isFailed = false)
            }
        }
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Failure", Icons.Default.Close) {
                lottieState = lottieState.copy(isPlaying = true, isSuccess = false, isFailed = true)
            }
            SimpleButton("Play/Pause", Icons.Default.PlayArrow) {
                lottieState = lottieState.copy(isPlaying = !lottieState.isPlaying)
            }
        }
    }
}
        
        
        

Why Try It: Uses LottieClipSpec.Progress to control specific animation segments. Great for forms or feedback screens.


3. Dynamic Animation Properties

Modify stroke width and opacity dynamically based on animation state for a customized look.


@Composable
fun DynamicLottieAnimation() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val dynamicProperties = rememberLottieDynamicProperties(
        rememberLottieDynamicProperty(
            property = LottieProperty.STROKE_WIDTH,
            value = if (lottieState.isSuccess) 5f else 2f,
            keyPath = arrayOf("**")
        ),
        rememberLottieDynamicProperty(
            property = LottieProperty.OPACITY,
            value = (lottieState.opacity * 100).toInt(),
            keyPath = arrayOf("**")
        )
    )
    LottieAnimation(
        composition = composition,
        progress = { animateLottieCompositionAsState(composition).value },
        modifier = Modifier.size(320.dp).padding(16.dp),
        dynamicProperties = dynamicProperties
    )
}
        
        
        

Why Try It: rememberLottieDynamicProperties lets you tweak animation visuals. Ideal for emphasizing states like success or failure.


4. Animated Scale and Rotation

Add smooth scale and rotation effects to the animation with spring and tween animations.


@Composable
fun AnimatedLottieTransform() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val scaleAnimation by animateFloatAsState(
        targetValue = lottieState.scale,
        animationSpec = tween(durationMillis = 500, easing = LinearEasing)
    )
    val rotationAnimation by animateFloatAsState(
        targetValue = lottieState.rotation,
        animationSpec = spring(dampingRatio = Spring.DampingRatioLowBouncy)
    )
    Column(
        modifier = Modifier.fillMaxSize().background(Color.White),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        LottieAnimation(
            composition = composition,
            progress = { animateLottieCompositionAsState(composition).value },
            modifier = Modifier
                .size(320.dp)
                .padding(16.dp)
                .graphicsLayer(
                    scaleX = scaleAnimation,
                    scaleY = scaleAnimation,
                    rotationZ = rotationAnimation,
                    transformOrigin = TransformOrigin.Center
                )
        )
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Scale", Icons.Default.Add) {
                lottieState = lottieState.copy(scale = if (lottieState.scale == 1f) 1.5f else 1f, isPlaying = true)
            }
            SimpleButton("Rotate", Icons.Default.Refresh) {
                lottieState = lottieState.copy(rotation = if (lottieState.rotation == 0f) 360f else 0f, isPlaying = true)
            }
        }
    }
}
        
        
        

Why Try It: Combines animateFloatAsState with graphicsLayer for smooth transformations. Perfect for interactive UI elements.


Which One's Best? A Quick Comparison

Here’s how the Lottie animation approaches compare, ranked by versatility and impact.

Lottie Animation in Jetpack Compose

Add Dynamic Lottie Animations in Jetpack Compose

Lottie animations bring your app to life with smooth, engaging visuals. Using Jetpack Compose, you can easily integrate animations with interactive controls like play, pause, speed, scale, and opacity. Let’s explore how to implement a Lottie animation with a loading, success, and failure sequence.

Lottie Animation Example

What’s Covered Here

We’ll use a Lottie animation with controls to toggle states (loading, success, failure), adjust speed, scale, rotation, and opacity. Each example includes copyable code and explanations. Let’s get started!

1. Basic Lottie Animation

Load and display a Lottie animation from a raw resource with default looping.


@Composable
fun BasicLottieAnimation() {
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    LottieAnimation(
        composition = composition,
        progress = { animateLottieCompositionAsState(composition).value },
        modifier = Modifier.size(320.dp).padding(16.dp)
    )
}
        
        
        

Why Try It: Simple setup with rememberLottieComposition. Ideal for basic loading animations.


2. Interactive State Controls

Add buttons to switch between loading, success, and failure states with specific animation ranges.


@Composable
fun InteractiveLottieAnimation() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val progress by animateLottieCompositionAsState(
        composition = composition,
        iterations = if (lottieState.isSuccess || lottieState.isFailed) 1 else LottieConstants.IterateForever,
        isPlaying = lottieState.isPlaying,
        clipSpec = LottieClipSpec.Progress(
            min = if (lottieState.isFailed) 0.499f else 0.0f,
            max = when {
                lottieState.isSuccess -> 0.44f
                lottieState.isFailed -> 0.95f
                else -> 0.282f
            }
        )
    )
    Column(
        modifier = Modifier.fillMaxSize().background(Color.White),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        LottieAnimation(
            composition = composition,
            progress = { progress },
            modifier = Modifier.size(320.dp).padding(16.dp)
        )
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Play Full", Icons.Default.PlayArrow) {
                lottieState = lottieState.copy(isPlaying = true, isSuccess = false, isFailed = false)
            }
            SimpleButton("Success", Icons.Default.Check) {
                lottieState = lottieState.copy(isPlaying = true, isSuccess = true, isFailed = false)
            }
        }
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Failure", Icons.Default.Close) {
                lottieState = lottieState.copy(isPlaying = true, isSuccess = false, isFailed = true)
            }
            SimpleButton("Play/Pause", Icons.Default.PlayArrow) {
                lottieState = lottieState.copy(isPlaying = !lottieState.isPlaying)
            }
        }
    }
}
@Composable
fun SimpleButton(text: String, icon: androidx.compose.ui.graphics.vector.ImageVector, onClick: () -> Unit) {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val scale by animateFloatAsState(
        targetValue = if (isPressed) 0.95f else 1f,
        animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy)
    )
    Button(
        onClick = onClick,
        modifier = Modifier
            .graphicsLayer(scaleX = scale, scaleY = scale)
            .padding(horizontal = 8.dp, vertical = 8.dp)
            .size(width = 140.dp, height = 48.dp),
        colors = ButtonDefaults.buttonColors(
            containerColor = Color(0xFF007BFF),
            contentColor = Color.White
        ),
        shape = RoundedCornerShape(25.dp),
        interactionSource = interactionSource,
        contentPadding = PaddingValues(horizontal = 12.dp)
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            Icon(
                imageVector = icon,
                contentDescription = null,
                modifier = Modifier.size(20.dp)
            )
            Text(text = text, fontSize = 14.sp)
        }
    }
}
        
        
        

Why Try It: Controls animation segments with LottieClipSpec.Progress. Perfect for user feedback like form submissions.


3. Dynamic Visual Adjustments

Dynamically change stroke width and opacity based on animation state.


@Composable
fun DynamicLottieAnimation() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val dynamicProperties = rememberLottieDynamicProperties(
        rememberLottieDynamicProperty(
            property = LottieProperty.STROKE_WIDTH,
            value = if (lottieState.isSuccess) 5f else 2f,
            keyPath = arrayOf("**")
        ),
        rememberLottieDynamicProperty(
            property = LottieProperty.OPACITY,
            value = (lottieState.opacity * 100).toInt(),
            keyPath = arrayOf("**")
        )
    )
    Column(
        modifier = Modifier.fillMaxSize().background(Color.White),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        LottieAnimation(
            composition = composition,
            progress = { animateLottieCompositionAsState(composition).value },
            modifier = Modifier.size(320.dp).padding(16.dp),
            dynamicProperties = dynamicProperties
        )
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Opacity", Icons.Default.Edit) {
                lottieState = lottieState.copy(opacity = if (lottieState.opacity == 1f) 0.5f else 1f, isPlaying = true)
            }
        }
    }
}
        
        
        

Why Try It: rememberLottieDynamicProperties customizes visuals dynamically. Great for highlighting specific states.


4. Scale and Rotation Effects

Apply smooth scale and rotation animations to enhance the Lottie visual.


@Composable
fun AnimatedLottieTransform() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val scaleAnimation by animateFloatAsState(
        targetValue = lottieState.scale,
        animationSpec = tween(durationMillis = 500, easing = LinearEasing)
    )
    val rotationAnimation by animateFloatAsState(
        targetValue = lottieState.rotation,
        animationSpec = spring(dampingRatio = Spring.DampingRatioLowBouncy)
    )
    Column(
        modifier = Modifier.fillMaxSize().background(Color.White),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        LottieAnimation(
            composition = composition,
            progress = { animateLottieCompositionAsState(composition).value },
            modifier = Modifier
                .size(320.dp)
                .padding(16.dp)
                .graphicsLayer(
                    scaleX = scaleAnimation,
                    scaleY = scaleAnimation,
                    rotationZ = rotationAnimation,
                    transformOrigin = TransformOrigin.Center
                )
        )
        Row(
            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Scale", Icons.Default.Add) {
                lottieState = lottieState.copy(scale = if (lottieState.scale == 1f) 1.5f else 1f, isPlaying = true)
            }
            SimpleButton("Rotate", Icons.Default.Refresh) {
                lottieState = lottieState.copy(rotation = if (lottieState.rotation == 0f) 360f else 0f, isPlaying = true)
            }
        }
    }
}
        
        
        

Why Try It: Uses animateFloatAsState and graphicsLayer for smooth transformations. Ideal for interactive UI elements like buttons or cards.


Which Approach is Best?

Here’s a ranked comparison of the Lottie animation approaches.

Rank Approach Pros Cons
1 Interactive State Controls Highly interactive; supports multiple states Requires state management
2 Scale and Rotation Effects Smooth animations; engaging visuals Extra animation setup
3 Dynamic Visual Adjustments Customizable visuals; state-specific tweaks Complex property setup
4 Basic Lottie Animation Simple; low resource usage Limited interactivity

Tips for Using Lottie in Jetpack Compose

  • Choose Animations Wisely: Use lightweight Lottie files for better performance.
  • Control States: Leverage LottieClipSpec for precise animation segments.
  • Smooth Animations: Use tween or spring for fluid transitions.
  • Test on Devices: Check performance on real devices to ensure smoothness.
  • Dynamic Properties: Experiment with LottieProperty for custom effects.

Common Questions

How Do I Add Lottie to My Project?

Add the Lottie Compose dependency: com.airbnb.android:lottie-compose in your build.gradle.


Can I Use Lottie for Buttons?

Yes! Place LottieAnimation inside a button composable.


Where to Find Lottie Files?

Check LottieFiles for free, high-quality animations.


Full Code to Copy and Run

Here’s the complete code for the Lottie animation demo. Paste it into your project to see it in action!


package com.android.uix

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.compose.*
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.TransformOrigin

class MainActivityLottie : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LottieSimpleDemoScreen()
        }
    }
}

data class LottieState(
    val isPlaying: Boolean = true,
    val speed: Float = 1f,
    val isSuccess: Boolean = false,
    val isFailed: Boolean = false,
    val scale: Float = 1f,
    val rotation: Float = 0f,
    val opacity: Float = 1f
)

@Composable
fun LottieSimpleDemoScreen() {
    var lottieState by remember { mutableStateOf(LottieState()) }
    val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.anim_loading_success_failed))
    val progress by animateLottieCompositionAsState(
        composition = composition,
        iterations = if (lottieState.isSuccess || lottieState.isFailed) 1 else LottieConstants.IterateForever,
        isPlaying = lottieState.isPlaying,
        speed = lottieState.speed,
        clipSpec = LottieClipSpec.Progress(
            min = if (lottieState.isFailed) 0.499f else 0.0f,
            max = when {
                lottieState.isSuccess -> 0.44f
                lottieState.isFailed -> 0.95f
                else -> 0.282f
            }
        )
    )
    val dynamicProperties = rememberLottieDynamicProperties(
        rememberLottieDynamicProperty(
            property = LottieProperty.STROKE_WIDTH,
            value = if (lottieState.isSuccess) 5f else 2f,
            keyPath = arrayOf("**")
        ),
        rememberLottieDynamicProperty(
            property = LottieProperty.OPACITY,
            value = (lottieState.opacity * 100).toInt(),
            keyPath = arrayOf("**")
        )
    )
    val scaleAnimation by animateFloatAsState(
        targetValue = lottieState.scale,
        animationSpec = tween(durationMillis = 500, easing = LinearEasing)
    )
    val rotationAnimation by animateFloatAsState(
        targetValue = lottieState.rotation,
        animationSpec = spring(dampingRatio = Spring.DampingRatioLowBouncy)
    )
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Lottie Demo",
            style = TextStyle(fontSize = 28.sp, fontWeight = FontWeight.Bold, color = Color.Black),
            modifier = Modifier.padding(top = 24.dp, bottom = 16.dp)
        )
        LottieAnimation(
            composition = composition,
            progress = { progress },
            modifier = Modifier
                .size(320.dp)
                .padding(16.dp)
                .graphicsLayer(
                    scaleX = scaleAnimation,
                    scaleY = scaleAnimation,
                    rotationZ = rotationAnimation,
                    transformOrigin = TransformOrigin.Center
                ),
            dynamicProperties = dynamicProperties
        )
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Play Full", Icons.Default.PlayArrow) {
                lottieState = lottieState.copy(
                    isPlaying = true,
                    isSuccess = false,
                    isFailed = false,
                    speed = 1f,
                    scale = 1f,
                    rotation = 0f,
                    opacity = 1f
                )
            }
            SimpleButton("Success", Icons.Default.Check) {
                lottieState = lottieState.copy(
                    isPlaying = true,
                    isSuccess = true,
                    isFailed = false,
                    speed = 1f,
                    scale = 1f,
                    rotation = 0f,
                    opacity = 1f
                )
            }
        }
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Failure", Icons.Default.Close) {
                lottieState = lottieState.copy(
                    isPlaying = true,
                    isSuccess = false,
                    isFailed = true,
                    speed = 1f,
                    scale = 1f,
                    rotation = 0f,
                    opacity = 1f
                )
            }
            SimpleButton("Play/Pause", Icons.Default.PlayArrow) {
                lottieState = lottieState.copy(
                    isPlaying = !lottieState.isPlaying
                )
            }
        }
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Speed Up", Icons.Default.ArrowForward) {
                lottieState = lottieState.copy(
                    speed = 1.5f,
                    isPlaying = true
                )
            }
            SimpleButton("Speed Down", Icons.Default.ArrowBack) {
                lottieState = lottieState.copy(
                    speed = 0.5f,
                    isPlaying = true
                )
            }
        }
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Scale", Icons.Default.Add) {
                lottieState = lottieState.copy(
                    scale = if (lottieState.scale == 1f) 1.5f else 1f,
                    isPlaying = true
                )
            }
            SimpleButton("Rotate", Icons.Default.Refresh) {
                lottieState = lottieState.copy(
                    rotation = if (lottieState.rotation == 0f) 360f else 0f,
                    isPlaying = true
                )
            }
        }
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            SimpleButton("Opacity", Icons.Default.Edit) {
                lottieState = lottieState.copy(
                    opacity = if (lottieState.opacity == 1f) 0.5f else 1f,
                    isPlaying = true
                )
            }
            SimpleButton("Reset", Icons.Default.Refresh) {
                lottieState = LottieState()
            }
        }
    }
}

@Composable
fun SimpleButton(text: String, icon: androidx.compose.ui.graphics.vector.ImageVector, onClick: () -> Unit) {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val scale by animateFloatAsState(
        targetValue = if (isPressed) 0.95f else 1f,
        animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy)
    )
    Button(
        onClick = onClick,
        modifier = Modifier
            .graphicsLayer(scaleX = scale, scaleY = scale)
            .padding(horizontal = 8.dp, vertical = 8.dp)
            .size(width = 140.dp, height = 48.dp),
        colors = ButtonDefaults.buttonColors(
            containerColor = Color(0xFF007BFF),
            contentColor = Color.White
        ),
        shape = RoundedCornerShape(25.dp),
        interactionSource = interactionSource,
        contentPadding = PaddingValues(horizontal = 12.dp)
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            Icon(
                imageVector = icon,
                contentDescription = null,
                modifier = Modifier.size(20.dp)
            )
            Text(text = text, fontSize = 14.sp)
        }
    }
}
        
        
        

Paste this into your Jetpack Compose project to see the full Lottie animation demo in action!

Post a Comment

Previous Post Next Post