Android ऐप (Compose) में एनिमेशन कैसे जोड़ें
Charmotion टीम द्वारा · अपडेट:

Android ऐप में एनिमेशन जोड़ने के लिए पहले Compose के built-in API इस्तेमाल करें: एक value के लिए animate*AsState, दिखाने और छिपाने के लिए AnimatedVisibility, और लूप के लिए rememberInfiniteTransition। डिज़ाइनर के बनाए वेक्टर लूप के लिए lottie-compose, इंटरैक्टिव कैरेक्टर के लिए app.rive:rive-android, और वीडियो क्लिप के लिए Media3 ExoPlayer जोड़ें।
मुख्य बातें
- Google का Compose decision tree हर केस को एक API से जोड़ता है,
animate*AsStateसे लेकरupdateTransitionतक। - MotionLayout View-based UI के लिए है; इसके docs नए projects को Compose animation की ओर भेजते हैं।
- जटिल illustrated एनिमेशन के लिए Google, Lottie जैसा कोई third-party framework सुझाता है।
- Rive का Compose API beta में है; legacy
RiveAnimationViewअभी भी स्टेट बदलने के सरल methods देता है। - लूपिंग वीडियो के लिए Media3 में एक
Playercomposable है।
पहले से कोई कैरेक्टर या लोगो है? अपने कैरेक्टर को असली ऐप स्क्रीन में देखें: स्प्लैश, ऑनबोर्डिंग, लोडिंग और एम्प्टी स्टेट स्क्रीन। यह फ़्री है, आपके ब्राउज़र में चलता है और कुछ भी अपलोड नहीं होता।
आपके केस के लिए कौन-सा Compose animation API सही है?
Google का "Choose an animation API" पेज एक decision tree की तरह काम करता है। संक्षेप में:
| केस | API |
|---|---|
| तय target वाली एक value (size, color, alpha) | animate*AsState, जैसे animateFloatAsState |
| कंटेंट दिखाना या छिपाना | AnimatedVisibility |
| एक composable की जगह दूसरा लाना | AnimatedContent या Crossfade |
| साथ-साथ बदलने वाली कई properties | updateTransition |
| हमेशा चलने वाला लूप | rememberInfiniteTransition |
| Gesture से चलने वाला मोशन | Animatable |
| आइकन का सरल micro-animation | AnimatedVectorDrawable |
| जटिल illustrated आर्ट | Lottie जैसा कोई third-party framework |
एक ऐसी row जोड़ें जो Google के chart में नहीं है: ऐसा कैरेक्टर जो ऐप के events पर रिएक्ट करे। इसके लिए स्टेट वाला रनटाइम चाहिए, जैसे Rive, ताकि एक ही फ़ाइल idle रह सके, loading के दौरान लूप चला सके और success पर रिएक्शन दे सके। तय क्लिप के लिए वीडियो इस्तेमाल करें।
अगर आपका ऐप अभी भी Views इस्तेमाल करता है, तो MotionLayout उपलब्ध है, लेकिन इसका documentation अब "Try the Compose way" नोटिस से शुरू होता है, जो Compose के animation API की ओर इशारा करता है।
animate*AsState और AnimatedVisibility कैसे काम करते हैं?
ये दोनों ज़्यादातर UI फ़ीडबैक संभाल लेते हैं। animateFloatAsState आपके दिए target की ओर एनिमेट करता है, हर बार जब target बदलता है:
@Composable
fun PressableCard(pressed: Boolean, showBanner: Boolean) {
val scale by animateFloatAsState(
targetValue = if (pressed) 0.95f else 1f,
label = "scale"
)
Column {
Card(Modifier.graphicsLayer { scaleX = scale; scaleY = scale }) { /* ... */ }
AnimatedVisibility(visible = showBanner) {
Text("Saved")
}
}
}
AnimatedVisibility default रूप से कंटेंट को fade और expand करके अंदर-बाहर लाता है, और custom enter और exit transitions भी स्वीकार करता है।
जब कई values को साथ में बदलना हो, जैसे select होने पर किसी card का size, color और elevation, तब updateTransition इस्तेमाल करें। यह सभी child animations को एक ही स्टेट से बाँध देता है, इसलिए वे एक ही पल में शुरू होते हैं और sync में रहते हैं।
लूप के लिए rememberInfiniteTransition तब तक चलता है जब तक composable स्क्रीन से बाहर न चला जाए:
val transition = rememberInfiniteTransition(label = "pulse")
val alpha by transition.animateFloat(
initialValue = 0.4f,
targetValue = 1f,
animationSpec = infiniteRepeatable(tween(800), RepeatMode.Reverse),
label = "alpha"
)
Box(Modifier.size(12.dp).alpha(alpha).background(Color.Gray, CircleShape))Compose में कंटेंट के बदलाव और आइकन को एनिमेट कैसे करें?
जब UI का एक हिस्सा दूसरे की जगह ले, जैसे कोई counter, status label या एम्प्टी स्टेट (जब स्क्रीन पर दिखाने को कुछ न हो) का list में बदलना, तब AnimatedContent इस्तेमाल करें। जब भी इसकी target स्टेट बदलती है, यह पुराने कंटेंट को एनिमेट करके बाहर और नए कंटेंट को एनिमेट करके अंदर लाता है:
AnimatedContent(targetState = count, label = "count") { value ->
Text("$value items")
}
Crossfade एक सरल विकल्प है: यह सिर्फ़ दो layouts के बीच fade करता है, जो tabs बदलने या loading और loaded स्टेट के बीच स्विच करने के लिए ठीक है। एक ही composable के अंदर size बदलने के लिए Modifier.animateContentSize() जोड़ें, फिर कंटेंट बदलने पर container आराम से बड़ा या छोटा होता है। Lists में Modifier.animateItem() items को जोड़ने, हटाने या क्रम बदलने पर एनिमेट करता है।
आइकन के लिए Google का decision tree सरल SVG micro-animations के लिए AnimatedVectorDrawable सुझाता है, जैसे play आइकन का pause में बदलना या checkmark का अपने-आप बनना। यह animators वाला एक vector drawable resource है, इसलिए यह XML के रूप में ship होता है और इसके लिए किसी अतिरिक्त library की ज़रूरत नहीं होती। इसे छोटे, एक काम वाले आइकन मोशन के लिए इस्तेमाल करें और पूरे illustrations के लिए Lottie रखें।
Navigation transitions navigation library का काम हैं: Compose Navigation के composable() destinations enterTransition और exitTransition स्वीकार करते हैं, इसलिए स्क्रीन बदलना बिना custom code के एनिमेट होता है।
Compose स्क्रीन में Lottie एनिमेशन कैसे जोड़ें?
Airbnb के lottie-android project से Compose artifact जोड़ें, उसकी README में दिए version के साथ:
implementation "com.airbnb.android:lottie-compose:$lottieVersion"
एक्सपोर्ट की गई .json फ़ाइल को res/raw/ में रखें, उसे composition के रूप में load करें और चलाएँ:
@Composable
fun LoadingAnimation() {
val composition by rememberLottieComposition(
LottieCompositionSpec.RawRes(R.raw.loading)
)
LottieAnimation(
composition,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(160.dp)
)
}
Composition asynchronously load होता है, इसलिए शुरुआती फ़्रेम में composition null रहता है; तैयार होने तक LottieAnimation कुछ भी draw नहीं करता। अगर आपको playback खुद कंट्रोल करना है, जैसे कोई task पूरा होने पर एक बार चलाना, तो animateLottieCompositionAsState इस्तेमाल करें और उसकी progress LottieAnimation को दें।
Lottie linear आर्ट के लिए सही है: spinner, success check, ऑनबोर्डिंग illustration। अगर किसी आइकन को सिर्फ़ सरल morph चाहिए, तो Google का tree इसकी जगह AnimatedVectorDrawable सुझाता है, जिसके लिए किसी अतिरिक्त library की ज़रूरत नहीं होती। अगर आर्ट का व्यवहार ऐप की स्टेट के हिसाब से बदलना हो, तो Rive पर विचार करें।

Android पर Rive एनिमेशन कैसे जोड़ें और स्टेट कैसे बदलें?
app.rive:rive-android (Rive के मौजूदा docs में 11.9.2) को androidx.startup के साथ जोड़ें, और .riv फ़ाइल को res/raw/ में रखें। Startup पर एक बार Rive.init(context) कॉल करें।
Rive का Compose API beta के रूप में marked है और Rive का नया काम इसी पर केंद्रित है। इसे एक worker चाहिए, यह फ़ाइल asynchronously load करता है और loading सफल होने पर render करता है:
setContent {
val riveWorker = rememberRiveWorker()
val riveFile = rememberRiveFile(
RiveFileSource.RawRes.from(R.raw.character),
riveWorker
)
when (riveFile) {
is Result.Loading -> CircularProgressIndicator()
is Result.Error -> Text("Animation unavailable")
is Result.Success -> Rive(riveFile.value)
}
}
Compose में view models वाली फ़ाइलें Rive के data binding API से कंट्रोल होती हैं; मौजूदा calls के लिए Rive के Android docs का Compose सेक्शन देखें।
legacy View API, जो RiveAnimationView पर आधारित है, अब भी सपोर्टेड है और इसमें हर इनपुट टाइप के लिए एक method है। यह XML layouts में या Compose के AndroidView के अंदर काम करता है:
val mascot = findViewById<RiveAnimationView>(R.id.mascot)
mascot.setNumberState("CharacterStateMachine", "mood", 5f) // loading loop
mascot.fireState("CharacterStateMachine", "success") // one-shot
नाम case-sensitive होते हैं। पूरा setup Android, Flutter और React Native पर Rive गाइड में है।
Media3 से लूपिंग वीडियो कैसे चलाएँ?
पहले से रेंडर की गई क्लिप के लिए Media3 ExoPlayer इस्तेमाल करें। मौजूदा docs में androidx.media3:media3-exoplayer:1.11.1 इस्तेमाल होता है, और media3-ui-compose-material3 एक Player composable देता है:
import androidx.media3.common.Player as Media3Player
@Composable
fun LoopingClip(uri: String) {
val context = LocalContext.current
val exo = remember {
ExoPlayer.Builder(context).build().apply {
setMediaItem(MediaItem.fromUri(uri))
repeatMode = Media3Player.REPEAT_MODE_ONE
volume = 0f
prepare()
play()
}
}
DisposableEffect(Unit) { onDispose { exo.release() } }
Player(player = exo)
}
volume को 0 पर सेट करने से सजावटी लूप साइलेंट रहता है। ऐप के साथ bundle की गई क्लिप के लिए remote URL की जगह bundled file की ओर इशारा करने वाला MediaItem इस्तेमाल करें, ताकि क्लिप offline भी उपलब्ध रहे और तुरंत शुरू हो।
जब composable स्क्रीन से हटे तो player को release करें, वरना वह बैकग्राउंड में decoding करता रहता है। वीडियो उन क्लिप के लिए सही है जिनमें फ़ोटोग्राफ़िक या 3D डिटेल हो। यह स्टेट पर रिएक्ट नहीं कर सकता, इसलिए जिस कैरेक्टर को idle और loading के बीच बदलना हो, उसके लिए Rive बेहतर है।
Android ऐप में एनिमेटेड मैस्कॉट कैसे जोड़ें?
मैस्कॉट को अपनी UI स्टेट के function की तरह मॉडल करें। ज़्यादातर ऐप पहले से किसी ViewModel से StateFlow देते हैं; हर स्टेट को मैस्कॉट के किसी एक लूप से मैप करें, और एक बार होने वाले events के लिए ट्रिगर फ़ायर करें:
- Idle स्क्रीन: मूड 0। Request चल रही है: मूड 5 (loading)।
- Request पूरी हुई:
successयाerrorफ़ायर करें, फिर idle पर लौटें। - Voice इनपुट: listening लूप; जवाब चल रहा है: talking लूप।
यह mapping एक ही जगह रखें। फिर स्क्रीन सिर्फ़ स्टेट भेजती हैं और फ़ाइल के अंदर की स्टेट मशीन transitions संभालती है, ताकि success रिएक्शन कभी अचानक न कटे।
Charmotion अपलोड किए गए मैस्कॉट या लोगो से इसी तरह की फ़ाइल बनाता है: एक .riv जिसमें CharacterStateMachine है (0 से 9 तक का mood इनपुट, साथ में success, error, enter और exit जैसे ट्रिगर), जो ऊपर दिए setNumberState और fireState calls के साथ काम करती है, और data binding के लिए एक Character व्यू मॉडल। स्टेट प्लान करने के लिए मैस्कॉट एनिमेशन स्टेट देखें।
Android एनिमेशन को smooth और accessible कैसे रखें?
Compose एनिमेशन तब हल्के रहते हैं जब वे drawing properties बदलते हैं। जहाँ हो सके, alpha, scale और translation को graphicsLayer के ज़रिए एनिमेट करें, और ऐसी values एनिमेट करने से बचें जिनसे हर फ़्रेम पर बड़े layout को फिर से measure करना पड़े।
- जब स्क्रीन दिखाई न दे रही हो तो infinite लूप रोकें और players को release करें।
- UI आर्टवर्क के लिए छोटी वेक्टर फ़ाइलें भेजें; वीडियो सिर्फ़ उन क्लिप के लिए रखें जिन्हें उसकी ज़रूरत हो।
- सिर्फ़ तेज़ laptop के emulator पर नहीं, किसी low-end device पर भी टेस्ट करें।
यूज़र की मोशन सेटिंग का सम्मान करें। Android 9 और उसके बाद के वर्ज़न पर लोग Settings > Accessibility > Remove animations चालू कर सकते हैं, जिससे system animator duration scale शून्य हो जाता है। Settings.Global.ANIMATOR_DURATION_SCALE चेक करें और जब यह 0 हो, तो लूप की जगह अपने मैस्कॉट का एक स्थिर फ़्रेम दिखाएँ। "loading" या "saved" जैसा मतलब टेक्स्ट में भी उपलब्ध रखें।
मोशन कम करें गाइड बताती है कि WCAG के हिसाब से यूज़र को किन लूप को pause कर पाना या उनसे बच पाना चाहिए।
Jetpack Compose ऐप में एनिमेशन जोड़ें
- API चुनें. Google का decision tree इस्तेमाल करें:
animate*AsState,AnimatedVisibility,updateTransitionयाrememberInfiniteTransition। - आर्टवर्क के लिए library जोड़ें. Lottie के लिए
com.airbnb.android:lottie-composeजोड़ें, या Rive के लिएapp.rive:rive-androidके साथandroidx.startup। - फ़ाइल bundle करें.
.jsonऔर.rivफ़ाइलों को lowercase और underscore वाले नामों के साथres/raw/में रखें। - इसे रेंडर करें.
LottieAnimationइस्तेमाल करें,rememberRiveFileसफल होने के बाद Rive काRive()composable, या Media3 काPlayercomposable। - स्टेट चलाएँ. ViewModel स्टेट को मूड नंबर और ट्रिगर से मैप करें, जैसे legacy view पर
setNumberStateऔरfireState। - मोशन सेटिंग चेक करें. जब animator duration scale 0 हो, तो एक स्थिर फ़्रेम दिखाएँ।
अक्सर पूछे जाने वाले सवाल
क्या MotionLayout अब भी recommended है?
सिर्फ़ View-based स्क्रीन के लिए। MotionLayout, ConstraintLayout और View system पर बना है, और इसकी documentation अब "Try the Compose way" नोटिस से शुरू होती है, जो नए projects को Compose के animation APIs की ओर भेजता है। Compose ऐप के लिए इसकी जगह animate*AsState, AnimatedContent, updateTransition और इनसे जुड़े APIs इस्तेमाल करें।
AnimatedVectorDrawable या Lottie?
सरल आइकन micro-animations के लिए AnimatedVectorDrawable इस्तेमाल करें, जैसे play आइकन का pause में बदलना; इसके लिए कोई अतिरिक्त library नहीं चाहिए। After Effects में बने जटिल illustrated एनिमेशन के लिए Lottie इस्तेमाल करें। Google का Compose decision tree भी सरल SVG आइकन और जटिल आर्टवर्क के बीच यही रेखा खींचता है।
क्या मुझे Rive का Compose API इस्तेमाल करना चाहिए या RiveAnimationView?
नई Compose स्क्रीन के लिए Compose API इस्तेमाल करें, क्योंकि Rive का development वहीं केंद्रित है, लेकिन ध्यान रखें कि यह beta के रूप में चिह्नित है। RiveAnimationView अब भी सपोर्टेड है और View-based layouts या setNumberState और fireState से कंट्रोल होने वाली input-based files के लिए आसान विकल्प है। Compose इसे AndroidView के ज़रिए host कर सकता है।
Compose एनिमेशन को हमेशा लूप में कैसे चलाएँ?
rememberInfiniteTransition इस्तेमाल करें और infiniteRepeatable के साथ किसी value को एनिमेट करें, जैसे pulse के लिए RepeatMode.Reverse के साथ tween(800)। लूप तब तक चलता है जब तक composable स्क्रीन पर है, और composition से हटते ही रुक जाता है। Lottie file के लिए अपना लूप लिखने के बजाय LottieAnimation को iterations = LottieConstants.IterateForever पास करें।
इस गाइड से झटपट जवाब
स्रोत
- Choose an animation API, Android Developers
- Manage motion and widget animation with MotionLayout, Android Developers
- lottie-android, Airbnb (GitHub)
- Android runtime, Rive
- Android runtime: Inputs (legacy), Rive
- Media3 ExoPlayer: Hello world, Android Developers