Compose में ऐनिमेशन के इस्तेमाल के लिए गाइड

Compose में पहले से मौजूद कई ऐनिमेशन मैकेनिज़्म होते हैं. इसलिए, यह तय करना मुश्किल हो सकता है कि कौनसा मैकेनिज़्म चुना जाए. यहां ऐनिमेशन के इस्तेमाल के सामान्य उदाहरणों की सूची दी गई है. आपके लिए उपलब्ध अलग-अलग एपीआई विकल्पों के पूरे सेट के बारे में ज़्यादा जानकारी के लिए, Compose ऐनिमेशन का पूरा दस्तावेज़ पढ़ें.

सामान्य कंपोज़ेबल प्रॉपर्टी को ऐनिमेट करना

Compose, इस्तेमाल में आसान एपीआई उपलब्ध कराता है. इनकी मदद से, ऐनिमेशन से जुड़े कई सामान्य मामलों को हल किया जा सकता है. इस सेक्शन में, कंपोज़ेबल की सामान्य प्रॉपर्टी को ऐनिमेट करने का तरीका बताया गया है.

दिखने / गायब होने का ऐनिमेशन

हरे रंग का कंपोज़ेबल, जो खुद को दिखा रहा है और छिपा रहा है
पहली इमेज. कॉलम में किसी आइटम के दिखने और गायब होने के लिए ऐनिमेशन जोड़ना

किसी कंपोज़ेबल को छिपाने या दिखाने के लिए, AnimatedVisibility का इस्तेमाल करें. AnimatedVisibility के अंदर मौजूद चाइल्ड व्यू, एंटर या एग्ज़िट ट्रांज़िशन के लिए Modifier.animateEnterExit() का इस्तेमाल कर सकते हैं.

var visible by remember {
    mutableStateOf(true)
}
// Animated visibility will eventually remove the item from the composition once the animation has finished.
AnimatedVisibility(visible) {
    // your composable here
    // ...
}

AnimatedVisibility के enter और exit पैरामीटर की मदद से, यह कॉन्फ़िगर किया जा सकता है कि कोई कंपोज़ेबल दिखने और गायब होने पर कैसा व्यवहार करे. ज़्यादा जानकारी के लिए, पूरा दस्तावेज़ पढ़ें.

किसी कंपोज़ेबल के दिखने की स्थिति को ऐनिमेट करने का एक और विकल्प है, animateFloatAsState का इस्तेमाल करके समय के साथ ऐल्फ़ा को ऐनिमेट करना:

var visible by remember {
    mutableStateOf(true)
}
val animatedAlpha by animateFloatAsState(
    targetValue = if (visible) 1.0f else 0f,
    label = "alpha"
)
Box(
    modifier = Modifier
        .size(200.dp)
        .graphicsLayer {
            alpha = animatedAlpha
        }
        .clip(RoundedCornerShape(8.dp))
        .background(colorGreen)
        .align(Alignment.TopCenter)
) {
}

हालांकि, ऐल्फ़ा वैल्यू बदलने पर, कंपोज़ेबल कंपोज़िशन में बना रहता है और वह जगह घेरता रहता है जिसमें उसे लेआउट किया गया है. इस वजह से, स्क्रीन रीडर और सुलभता से जुड़े अन्य टूल, स्क्रीन पर मौजूद आइटम को अब भी ऐक्सेस कर सकते हैं. वहीं दूसरी ओर, AnimatedVisibility कंपोज़िशन से आइटम को हटा देता है.

किसी कंपोज़ेबल के ऐल्फ़ा को ऐनिमेट करना
दूसरी इमेज. कंपोज़ेबल के ऐल्फ़ा को ऐनिमेट करना

बैकग्राउंड के रंग को ऐनिमेट करना

ऐसा कंपोज़ेबल जिसका बैकग्राउंड कलर, ऐनिमेशन के तौर पर समय के साथ बदलता है. इसमें रंग एक-दूसरे में फ़ेड हो रहे हैं.
तीसरी इमेज. कंपोज़ेबल के बैकग्राउंड के रंग को ऐनिमेट करना

val animatedColor by animateColorAsState(
    if (animateBackgroundColor) colorGreen else colorBlue,
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(animatedColor)
    }
) {
    // your composable here
}

यह विकल्प, Modifier.background() का इस्तेमाल करने से ज़्यादा बेहतर परफ़ॉर्म करता है. Modifier.background() का इस्तेमाल, एक बार में रंग सेट करने के लिए किया जा सकता है. हालांकि, समय के साथ किसी रंग को ऐनिमेट करने पर, ज़रूरत से ज़्यादा रीकंपोज़िशन हो सकते हैं.

बैकग्राउंड के रंग को लगातार ऐनिमेट करने के लिए, ऐनिमेशन को दोहराना सेक्शन देखें.

किसी कंपोज़ेबल के साइज़ को ऐनिमेट करना

हरे रंग का कंपोज़ेबल, अपने साइज़ में बदलाव को आसानी से ऐनिमेट कर रहा है.
चौथी इमेज. छोटे और बड़े साइज़ के बीच आसानी से ऐनिमेट होने वाला कंपोज़ेबल

Compose की मदद से, कंपोज़ेबल के साइज़ को अलग-अलग तरीकों से ऐनिमेट किया जा सकता है. कंपोज़ेबल के साइज़ में होने वाले बदलावों के बीच ऐनिमेशन के लिए, animateContentSize() का इस्तेमाल करें.

उदाहरण के लिए, अगर आपके पास कोई ऐसा बॉक्स है जिसमें मौजूद टेक्स्ट को एक से ज़्यादा लाइनों में बड़ा किया जा सकता है, तो ज़्यादा आसान ट्रांज़िशन पाने के लिए Modifier.animateContentSize() का इस्तेमाल किया जा सकता है:

var expanded by remember { mutableStateOf(false) }
Box(
    modifier = Modifier
        .background(colorBlue)
        .animateContentSize()
        .height(if (expanded) 400.dp else 200.dp)
        .fillMaxWidth()
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            expanded = !expanded
        }

) {
}

AnimatedContent का इस्तेमाल SizeTransform के साथ भी किया जा सकता है. इससे यह बताया जा सकता है कि साइज़ में बदलाव कैसे होने चाहिए.

कंपोज़ेबल की पोज़िशन को ऐनिमेट करना

हरे रंग का कंपोज़ेबल, आसानी से नीचे और दाईं ओर ऐनिमेट हो रहा है
पांचवीं इमेज. ऑफ़सेट के हिसाब से कंपोज़ेबल को मूव करना

किसी कंपोज़ेबल की पोज़िशन को ऐनिमेट करने के लिए, Modifier.offset{ } के साथ animateIntOffsetAsState() का इस्तेमाल करें.

var moved by remember { mutableStateOf(false) }
val pxToMove = with(LocalDensity.current) {
    100.dp.toPx().roundToInt()
}
val offset by animateIntOffsetAsState(
    targetValue = if (moved) {
        IntOffset(pxToMove, pxToMove)
    } else {
        IntOffset.Zero
    },
    label = "offset"
)

Box(
    modifier = Modifier
        .offset {
            offset
        }
        .background(colorBlue)
        .size(100.dp)
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            moved = !moved
        }
)

अगर आपको यह पक्का करना है कि पोज़िशन या साइज़ को ऐनिमेट करते समय, कंपोज़ेबल अन्य कंपोज़ेबल के ऊपर या नीचे न दिखें, तो Modifier.layout{ } का इस्तेमाल करें. यह मॉडिफ़ायर, साइज़ और पोज़िशन में होने वाले बदलावों को पैरंट कॉम्पोनेंट पर लागू करता है. इससे अन्य चाइल्ड कॉम्पोनेंट पर असर पड़ता है.

उदाहरण के लिए, अगर आपको किसी Box को Column के अंदर ले जाना है और Box के मूव होने पर अन्य चाइल्ड एलिमेंट को भी मूव करना है, तो Modifier.layout{ } के साथ ऑफ़सेट की जानकारी इस तरह शामिल करें:

var toggled by remember {
    mutableStateOf(false)
}
val interactionSource = remember {
    MutableInteractionSource()
}
Column(
    modifier = Modifier
        .padding(16.dp)
        .fillMaxSize()
        .clickable(indication = null, interactionSource = interactionSource) {
            toggled = !toggled
        }
) {
    val offsetTarget = if (toggled) {
        IntOffset(150, 150)
    } else {
        IntOffset.Zero
    }
    val offset = animateIntOffsetAsState(
        targetValue = offsetTarget, label = "offset"
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
    Box(
        modifier = Modifier
            .layout { measurable, constraints ->
                val offsetValue = if (isLookingAhead) offsetTarget else offset.value
                val placeable = measurable.measure(constraints)
                layout(placeable.width + offsetValue.x, placeable.height + offsetValue.y) {
                    placeable.placeRelative(offsetValue)
                }
            }
            .size(100.dp)
            .background(colorGreen)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
}

दो बॉक्स,जिनमें से दूसरा बॉक्स अपनी X, Y पोज़िशन को ऐनिमेट कर रहा है. तीसरा बॉक्स भी Y पोज़िशन पर मूव करके रिस्पॉन्स कर रहा है.
छठी इमेज. Modifier.layout{ }
की मदद से ऐनिमेट करना

किसी कंपोज़ेबल की पैडिंग को ऐनिमेट करना

हरे रंग का कंपोज़ेबल, क्लिक करने पर छोटा और बड़ा हो रहा है. साथ ही, पैडिंग ऐनिमेट हो रही है
सातवीं इमेज. पैडिंग ऐनिमेशन के साथ कंपोज़ेबल

किसी कंपोज़ेबल की पैडिंग को ऐनिमेट करने के लिए, animateDpAsState के साथ Modifier.padding() का इस्तेमाल करें:

var toggled by remember {
    mutableStateOf(false)
}
val animatedPadding by animateDpAsState(
    if (toggled) {
        0.dp
    } else {
        20.dp
    },
    label = "padding"
)
Box(
    modifier = Modifier
        .aspectRatio(1f)
        .fillMaxSize()
        .padding(animatedPadding)
        .background(Color(0xff53D9A1))
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            toggled = !toggled
        }
)

किसी कंपोज़ेबल के एलिवेशन को ऐनिमेट करना

आठवीं इमेज. क्लिक करने पर, कंपोज़ेबल का एलिवेशन ऐनिमेट हो रहा है

किसी कंपोज़ेबल के एलिवेशन को ऐनिमेट करने के लिए, animateDpAsState के साथ Modifier.graphicsLayer{ } का इस्तेमाल करें. एक बार में एलिवेशन में बदलाव करने के लिए, Modifier.shadow() का इस्तेमाल करें. अगर आपको शैडो को ऐनिमेट करना है, तो Modifier.graphicsLayer{ } मॉडिफ़ायर का इस्तेमाल करना बेहतर विकल्प है.

val mutableInteractionSource = remember {
    MutableInteractionSource()
}
val pressed = mutableInteractionSource.collectIsPressedAsState()
val elevation = animateDpAsState(
    targetValue = if (pressed.value) {
        32.dp
    } else {
        8.dp
    },
    label = "elevation"
)
Box(
    modifier = Modifier
        .size(100.dp)
        .align(Alignment.Center)
        .graphicsLayer {
            this.shadowElevation = elevation.value.toPx()
        }
        .clickable(interactionSource = mutableInteractionSource, indication = null) {
        }
        .background(colorGreen)
) {
}

इसके अलावा, Card कंपोज़ेबल का इस्तेमाल करें और हर स्टेट के लिए, एलिवेशन प्रॉपर्टी को अलग-अलग वैल्यू पर सेट करें.

टेक्स्ट स्केल, ट्रांसलेशन या रोटेशन को ऐनिमेट करना

टेक्स्ट कंपोज़ेबल में, छोटे और बड़े साइज़ के बीच ऐनिमेट होने वाला Hello टेक्स्ट.
नौवीं इमेज. टेक्स्ट का साइज़ आसानी से छोटा या बड़ा हो रहा है

टेक्स्ट के स्केल, ट्रांसलेशन या रोटेशन को ऐनिमेट करते समय, TextStyle पर textMotion पैरामीटर को TextMotion.Animated पर सेट करें. इससे टेक्स्ट ऐनिमेशन के बीच ट्रांज़िशन आसान हो जाता है. टेक्स्ट को ट्रांसलेट करने, घुमाने या उसका साइज़ बदलने के लिए, Modifier.graphicsLayer{ } का इस्तेमाल करें.

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 8f,
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "scale"
)
Box(modifier = Modifier.fillMaxSize()) {
    Text(
        text = "Hello",
        modifier = Modifier
            .graphicsLayer {
                scaleX = scale
                scaleY = scale
                transformOrigin = TransformOrigin.Center
            }
            .align(Alignment.Center),
        // Text composable does not take TextMotion as a parameter.
        // Provide it via style argument but make sure that we are copying from current theme
        style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated)
    )
}

टेक्स्ट के रंग को ऐनिमेट करना

'नमस्ते कंपोज़' शब्दों का रंग, हरे और नीले रंग के बीच ऐनिमेट हो रहा है
इमेज 10. टेक्स्ट के रंग को ऐनिमेट करने का उदाहरण

टेक्स्ट के रंग को ऐनिमेट करने के लिए, BasicText कंपोज़ेबल पर color लैम्डा का इस्तेमाल करें:

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val animatedColor by infiniteTransition.animateColor(
    initialValue = Color(0xFF60DDAD),
    targetValue = Color(0xFF4285F4),
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "color"
)

BasicText(
    text = "Hello Compose",
    color = {
        animatedColor
    },
    // ...
)

अलग-अलग तरह के कॉन्टेंट के बीच स्विच करना

हरे रंग की स्क्रीन पर 'लोड हो रहा है', नीले रंग की स्क्रीन पर 'लोड हो गया', और सफ़ेद रंग की स्क्रीन पर 'गड़बड़ी' लिखा हुआ है. एक आसान ऐनिमेशन के साथ, अलग-अलग कंपोज़ेबल को बार-बार दिखाया जा रहा है.
इमेज 11. अलग-अलग कंपोज़ेबल के बीच होने वाले बदलावों को ऐनिमेट करने के लिए, AnimatedContent का इस्तेमाल करना (धीमा किया गया)

अलग-अलग कंपोज़ेबल के बीच ऐनिमेशन दिखाने के लिए, AnimatedContent का इस्तेमाल करें. अगर आपको कंपोज़ेबल के बीच सिर्फ़ स्टैंडर्ड फ़ेड इफ़ेक्ट चाहिए, तो Crossfade का इस्तेमाल करें.

var state by remember {
    mutableStateOf(UiState.Loading)
}
AnimatedContent(
    state,
    transitionSpec = {
        fadeIn(
            animationSpec = tween(3000)
        ) togetherWith fadeOut(animationSpec = tween(3000))
    },
    modifier = Modifier.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null
    ) {
        state = when (state) {
            UiState.Loading -> UiState.Loaded
            UiState.Loaded -> UiState.Error
            UiState.Error -> UiState.Loading
        }
    },
    label = "Animated Content"
) { targetState ->
    when (targetState) {
        UiState.Loading -> {
            LoadingScreen()
        }
        UiState.Loaded -> {
            LoadedScreen()
        }
        UiState.Error -> {
            ErrorScreen()
        }
    }
}

AnimatedContent को अपनी पसंद के मुताबिक बनाया जा सकता है, ताकि कई तरह के एंटर और एग्ज़िट ट्रांज़िशन दिखाए जा सकें. ज़्यादा जानकारी के लिए, AnimatedContent के बारे में दस्तावेज़ पढ़ें या AnimatedContent के बारे में यह ब्लॉग पोस्ट पढ़ें.

अलग-अलग डेस्टिनेशन पर नेविगेट करते समय ऐनिमेशन दिखाना

दो कंपोज़ेबल हैं. इनमें से एक हरे रंग का है, जिस पर लैंडिंग लिखा है और दूसरा नीले रंग का है, जिस पर जानकारी लिखा है. जानकारी वाले कंपोज़ेबल को लैंडिंग वाले कंपोज़ेबल के ऊपर स्लाइड करके ऐनिमेट किया जा रहा है.
इमेज 12. navigation-compose का इस्तेमाल करके, कंपोज़ेबल के बीच ऐनिमेशन बनाना

navigation-compose आर्टफ़ैक्ट का इस्तेमाल करते समय, कंपोज़ेबल के बीच ट्रांज़िशन को ऐनिमेट करने के लिए, कंपोज़ेबल पर enterTransition और exitTransition तय करें. टॉप लेवल NavHost पर, सभी डेस्टिनेशन के लिए डिफ़ॉल्ट ऐनिमेशन भी सेट किया जा सकता है:

val navController = rememberNavController()
NavHost(
    navController = navController, startDestination = "landing",
    enterTransition = { EnterTransition.None },
    exitTransition = { ExitTransition.None }
) {
    composable("landing") {
        ScreenLanding(
            // ...
        )
    }
    composable(
        "detail/{photoUrl}",
        arguments = listOf(navArgument("photoUrl") { type = NavType.StringType }),
        enterTransition = {
            fadeIn(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideIntoContainer(
                animationSpec = tween(300, easing = EaseIn),
                towards = AnimatedContentTransitionScope.SlideDirection.Start
            )
        },
        exitTransition = {
            fadeOut(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideOutOfContainer(
                animationSpec = tween(300, easing = EaseOut),
                towards = AnimatedContentTransitionScope.SlideDirection.End
            )
        }
    ) { backStackEntry ->
        ScreenDetails(
            // ...
        )
    }
}

एंटर और एग्ज़िट ट्रांज़िशन कई तरह के होते हैं. ये आने वाले और जाने वाले कॉन्टेंट पर अलग-अलग इफ़ेक्ट लागू करते हैं. ज़्यादा जानकारी के लिए, दस्तावेज़ देखें.

ऐनिमेशन को दोहराना

हरे रंग का बैकग्राउंड, जो नीले रंग के बैकग्राउंड में बदल जाता है. यह दोनों रंगों के बीच ऐनिमेशन के ज़रिए लगातार बदलता रहता है.
इमेज 13. बैकग्राउंड का रंग, दो वैल्यू के बीच लगातार ऐनिमेट हो रहा है

अपने ऐनिमेशन को लगातार दोहराने के लिए, infiniteRepeatable animationSpec के साथ rememberInfiniteTransition का इस्तेमाल करें. RepeatMode को बदलें, ताकि यह तय किया जा सके कि यह आगे और पीछे कैसे जाए.

किसी सेट को तय संख्या में दोहराने के लिए, repeatable का इस्तेमाल करें.

val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val color by infiniteTransition.animateColor(
    initialValue = Color.Green,
    targetValue = Color.Blue,
    animationSpec = infiniteRepeatable(
        animation = tween(1000, easing = LinearEasing),
        repeatMode = RepeatMode.Reverse
    ),
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(color)
    }
) {
    // your composable here
}

किसी कंपोज़ेबल के लॉन्च होने पर ऐनिमेशन शुरू करना

LaunchedEffect तब चलता है, जब कोई कंपोज़ेबल, कंपोज़िशन में शामिल होता है. यह कंपोज़ेबल के लॉन्च होने पर ऐनिमेशन शुरू करता है. इसका इस्तेमाल, ऐनिमेशन की स्थिति में बदलाव करने के लिए किया जा सकता है. लॉन्च होने पर ऐनिमेशन शुरू करने के लिए, animateTo तरीके के साथ Animatable का इस्तेमाल करना:

val alphaAnimation = remember {
    Animatable(0f)
}
LaunchedEffect(Unit) {
    alphaAnimation.animateTo(1f)
}
Box(
    modifier = Modifier.graphicsLayer {
        alpha = alphaAnimation.value
    }
)

क्रम में चलने वाले ऐनिमेशन बनाना

चार सर्कल, जिनमें से हर एक के बीच हरे रंग के ऐरो हैं. ये ऐरो एक के बाद एक ऐनिमेट हो रहे हैं.
इमेज 14. एक डायग्राम, जिसमें दिखाया गया है कि क्रम में चलने वाला ऐनिमेशन, एक-एक करके कैसे आगे बढ़ता है.

क्रम में या एक साथ चलने वाले ऐनिमेशन के लिए, Animatable कोरूटीन एपीआई का इस्तेमाल करें. Animatable पर एक के बाद एक animateTo को कॉल करने से, हर ऐनिमेशन को आगे बढ़ने से पहले, पिछले ऐनिमेशन के खत्म होने का इंतज़ार करना पड़ता है. ऐसा इसलिए है, क्योंकि यह एक सस्पेंड फ़ंक्शन है.

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    alphaAnimation.animateTo(1f)
    yAnimation.animateTo(100f)
    yAnimation.animateTo(500f, animationSpec = tween(100))
}

एक साथ कई ऐनिमेशन बनाना

हरे रंग के ऐरो वाले तीन सर्कल, एक-एक करके ऐनिमेट हो रहे हैं. इसके बाद, तीनों एक साथ ऐनिमेट हो रहे हैं.
इमेज 15. एक साथ चलने वाले ऐनिमेशन की प्रोग्रेस दिखाने वाला डायग्राम.

एक साथ कई ऐनिमेशन दिखाने के लिए, कोरूटीन एपीआई (Animatable#animateTo() या animate) या Transition एपीआई का इस्तेमाल करें. अगर कोरूटीन कॉन्टेक्स्ट में कई लॉन्च फ़ंक्शन इस्तेमाल किए जाते हैं, तो यह ऐनिमेशन को एक ही समय पर लॉन्च करता है:

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    launch {
        alphaAnimation.animateTo(1f)
    }
    launch {
        yAnimation.animateTo(100f)
    }
}

updateTransition एपीआई का इस्तेमाल करके, एक ही स्टेट से एक ही समय पर कई अलग-अलग प्रॉपर्टी ऐनिमेशन चलाए जा सकते हैं. इस उदाहरण में, स्थिति में बदलाव करके कंट्रोल की जाने वाली दो प्रॉपर्टी को ऐनिमेट किया गया है. ये प्रॉपर्टी हैं: rect और borderWidth:

var currentState by remember { mutableStateOf(BoxState.Collapsed) }
val transition = updateTransition(currentState, label = "transition")

val rect by transition.animateRect(label = "rect") { state ->
    when (state) {
        BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f)
        BoxState.Expanded -> Rect(100f, 100f, 300f, 300f)
    }
}
val borderWidth by transition.animateDp(label = "borderWidth") { state ->
    when (state) {
        BoxState.Collapsed -> 1.dp
        BoxState.Expanded -> 0.dp
    }
}

एनिमेशन की परफ़ॉर्मेंस को ऑप्टिमाइज़ करना

Compose में ऐनिमेशन की वजह से, परफ़ॉर्मेंस से जुड़ी समस्याएं आ सकती हैं. ऐसा इसलिए होता है, क्योंकि ऐनिमेशन में स्क्रीन पर मौजूद पिक्सल को तेज़ी से मूव किया जाता है या उनमें बदलाव किया जाता है. यह बदलाव फ़्रेम-दर-फ़्रेम होता है, ताकि मूवमेंट का भ्रम पैदा किया जा सके.

Compose के अलग-अलग फ़ेज़ को ध्यान में रखें: कंपोज़िशन, लेआउट, और ड्रॉ. अगर आपका ऐनिमेशन, लेआउट फ़ेज़ में बदलाव करता है, तो इससे जिन कॉम्पोज़ेबल पर असर पड़ा है उन्हें फिर से लेआउट और ड्रॉ करना होगा. अगर आपका ऐनिमेशन ड्रॉ फ़ेज़ में होता है, तो यह डिफ़ॉल्ट रूप से ज़्यादा बेहतर परफ़ॉर्म करता है. ऐसा तब होता है, जब ऐनिमेशन को लेआउट फ़ेज़ में चलाया जाता है, क्योंकि इसमें कुल मिलाकर कम काम करना पड़ता है.

ऐनिमेशन के दौरान आपका ऐप्लिकेशन कम से कम काम करे, इसके लिए जहां भी हो सके Modifier का लैम्डा वर्शन चुनें. यह रीकंपोज़िशन को स्किप करता है और कंपोज़िशन फ़ेज़ के बाहर ऐनिमेशन को लागू करता है. इसके अलावा, Modifier.graphicsLayer{ } का इस्तेमाल करें, क्योंकि यह मॉडिफ़ायर हमेशा ड्रॉ फ़ेज़ में चलता है. इस बारे में ज़्यादा जानकारी के लिए, परफ़ॉर्मेंस से जुड़े दस्तावेज़ में रीड को बाद में करना सेक्शन देखें.

ऐनिमेशन की समयावधि बदलना

Compose, ज़्यादातर ऐनिमेशन के लिए डिफ़ॉल्ट रूप से स्प्रिंग ऐनिमेशन का इस्तेमाल करता है. स्प्रिंग या फ़िज़िक्स पर आधारित ऐनिमेशन, ज़्यादा नैचुरल लगते हैं. इन्हें रोका भी जा सकता है, क्योंकि ये किसी तय समय के बजाय, ऑब्जेक्ट की मौजूदा वेलोसिटी को ध्यान में रखते हैं. अगर आपको डिफ़ॉल्ट सेटिंग को बदलना है, तो पहले दिखाए गए सभी Animation API में animationSpec सेट करने की सुविधा होती है. इससे ऐनिमेशन के चलने के तरीके को पसंद के मुताबिक बनाया जा सकता है. इससे यह तय किया जा सकता है कि आपको ऐनिमेशन को किसी खास अवधि तक चलाना है या उसे ज़्यादा बाउंस करना है.

यहां animationSpec के अलग-अलग विकल्पों की खास जानकारी दी गई है:

  • spring: फ़िज़िक्स पर आधारित ऐनिमेशन. यह सभी ऐनिमेशन के लिए डिफ़ॉल्ट तौर पर सेट होता है. ऐनिमेशन को अलग लुक और स्टाइल देने के लिए, स्टिफ़नेस या डैंपिंग रेशियो को बदला जा सकता है.
  • tween (between का छोटा रूप): यह अवधि के हिसाब से ऐनिमेशन है. यह Easing फ़ंक्शन की मदद से, दो वैल्यू के बीच ऐनिमेशन दिखाता है.
  • keyframes: ऐनिमेशन में कुछ मुख्य पॉइंट पर वैल्यू तय करने के लिए खास जानकारी.
  • repeatable: यह अवधि के हिसाब से तय की गई ऐसी शर्त है जो RepeatMode के हिसाब से तय की गई संख्या के मुताबिक चलती है.
  • infiniteRepeatable: अवधि के हिसाब से तय की गई ऐसी शर्त जो हमेशा लागू रहती है.
  • snap: बिना किसी ऐनिमेशन के, तुरंत आखिरी वैल्यू पर स्नैप करता है.
दो ऐनिमेशन, जिनमें से एक में कोई स्प्रिंग सेट नहीं है और दूसरे में कस्टम स्प्रिंग सेट है.
16वीं इमेज. कोई स्पेक सेट नहीं है बनाम कस्टम स्प्रिंग स्पेक सेट

animationSpecs के बारे में ज़्यादा जानने के लिए, पूरा दस्तावेज़ पढ़ें.

अन्य संसाधन

Compose में मज़ेदार ऐनिमेशन के और उदाहरण देखने के लिए, यहां जाएं: