התכונה 'פיתוח נייטיב' כוללת תכנים קומפוזביליים ומגבילי התאמה מובנים לצורך טיפול בתרחישים נפוצים לדוגמה באנימציה.
תכנים קומפוזביליים מובנים באנימציה
עם AnimatedVisibility
אפשר להפוך את המראה והיעלם לאנימציה
![תוכן קומפוזבילי ירוק שמציג ומסתיר את עצמו](https://developer.android.com/static/develop/ui/compose/images/animations/animated_visibility_column.gif?hl=he)
AnimatedVisibility
שמזינים בו אנימציה של המראה וההיעלמות של התוכן שלו,
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 // ... }
כברירת מחדל, התוכן מופיע באופן הדרגתי ומתרחב, והוא נעלם
אתם נעלמים ומתכווצים. ניתן להתאים אישית את המעבר על ידי ציון
EnterTransition
וגם
ExitTransition
var visible by remember { mutableStateOf(true) } val density = LocalDensity.current AnimatedVisibility( visible = visible, enter = slideInVertically { // Slide in from 40 dp from the top. with(density) { -40.dp.roundToPx() } } + expandVertically( // Expand from the top. expandFrom = Alignment.Top ) + fadeIn( // Fade in with the initial alpha of 0.3f. initialAlpha = 0.3f ), exit = slideOutVertically() + shrinkVertically() + fadeOut() ) { Text("Hello", Modifier.fillMaxWidth().height(200.dp)) }
כמו שאפשר לראות בדוגמה שלמעלה, אפשר לשלב כמה נכסים מסוג EnterTransition
או ExitTransition
אובייקטים עם אופרטור +
, וכל אחד מהם מקבל ערך אופציונלי
כדי להתאים אישית את ההתנהגות. מידע נוסף זמין בחומרי העזר.
EnterTransition
ו-ExitTransition
דוגמאות
ב-AnimatedVisibility
יש גם וריאנט שלוקח
MutableTransitionState
. כך אפשר להפעיל אנימציה ברגע
AnimatedVisibility
נוסף לעץ היצירה. הוא שימושי גם למקרים הבאים:
לצפות במצב האנימציה.
// Create a MutableTransitionState<Boolean> for the AnimatedVisibility. val state = remember { MutableTransitionState(false).apply { // Start the animation immediately. targetState = true } } Column { AnimatedVisibility(visibleState = state) { Text(text = "Hello, world!") } // Use the MutableTransitionState to know the current animation state // of the AnimatedVisibility. Text( text = when { state.isIdle && state.currentState -> "Visible" !state.isIdle && state.currentState -> "Disappearing" state.isIdle && !state.currentState -> "Invisible" else -> "Appearing" } ) }
הצגת אנימציה של כניסה ויציאה לילדים
תוכן בתוך AnimatedVisibility
(ילדים ישירים או עקיפים) יכול להשתמש
animateEnterExit
כדי לציין התנהגות אנימציה שונה לכל אחד מהם. הרכיבים החזותיים
לכל אחד מהילדים האלו הוא שילוב של האנימציות שצוינו
בקובץ הקומפוזבילי AnimatedVisibility
, ובקלט של הילד או הילדה
יציאה מאנימציות.
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // Fade in/out the background and the foreground. Box(Modifier.fillMaxSize().background(Color.DarkGray)) { Box( Modifier .align(Alignment.Center) .animateEnterExit( // Slide in/out the inner box. enter = slideInVertically(), exit = slideOutVertically() ) .sizeIn(minWidth = 256.dp, minHeight = 64.dp) .background(Color.Red) ) { // Content of the notification… } } }
במקרים מסוימים, ייתכן שברצונך שהאפקט של AnimatedVisibility
לא יכלול אנימציות של
כדי שלילדים יהיו אנימציות ייחודיות משלהם
animateEnterExit
. כדי לעשות זאת, צריך לציין EnterTransition.None
ExitTransition.None
בתוכן הקומפוזבילי AnimatedVisibility
.
הוספת אנימציה מותאמת אישית
אם רוצים להוסיף אפקטים של אנימציה בהתאמה אישית, מעבר לכניסה וליציאה המובנות
אנימציות, לגשת למכונה Transition
הבסיסית דרך transition
נכס בתוך lambda של התוכן עבור AnimatedVisibility
. כל אנימציה
שנוספו למכונת המעבר יפעלו בו-זמנית עם הפקודה Enter
ולצאת מאנימציות של AnimatedVisibility
. AnimatedVisibility
בהמתנה עד
כל האנימציות בTransition
הסתיימו לפני הסרת התוכן.
לאנימציות יציאה שנוצרו ללא תלות ב-Transition
(כמו שימוש ב-
animate*AsState
), ל-AnimatedVisibility
לא תהיה אפשרות להתייחס אליהם,
ולכן הם עשויים להסיר את התוכן הקומפוזבילי לפני שהם מסיימים.
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // this: AnimatedVisibilityScope // Use AnimatedVisibilityScope#transition to add a custom animation // to the AnimatedVisibility. val background by transition.animateColor(label = "color") { state -> if (state == EnterExitState.Visible) Color.Blue else Color.Gray } Box(modifier = Modifier.size(128.dp).background(background)) }
לפרטים על Transition
, ראו עדכון מעבר.
אנימציה על סמך מצב היעד עם AnimatedContent
AnimatedContent
קומפוזבילי אנימציה בתוכן שלו כשהוא משתנה על סמך
במצב היעד.
Row { var count by remember { mutableStateOf(0) } Button(onClick = { count++ }) { Text("Add") } AnimatedContent(targetState = count) { targetCount -> // Make sure to use `targetCount`, not `count`. Text(text = "Count: $targetCount") } }
שימו לב שתמיד צריך להשתמש בפרמטר lambda ולשקף אותו תוכן. ה-API משתמש בערך הזה כמפתח לזיהוי התוכן מוצגת כרגע.
כברירת מחדל, התוכן הראשוני נעלם ולאחר מכן תוכן היעד נעלם
(ההתנהגות הזו נקראת מעבר הדרגתי). שלך
יכולים להתאים אישית את התנהגות האנימציה הזו על ידי ציון אובייקט ContentTransform
פרמטר transitionSpec
. אפשר ליצור ContentTransform
על ידי שילוב
EnterTransition
עם ExitTransition
באמצעות פונקציית ההוספה with
. אפשר להחיל את SizeTransform
אל ContentTransform
באמצעות צירוף
פונקציית תיקון using
.
AnimatedContent( targetState = count, transitionSpec = { // Compare the incoming number with the previous number. if (targetState > initialState) { // If the target number is larger, it slides up and fades in // while the initial (smaller) number slides up and fades out. slideInVertically { height -> height } + fadeIn() with slideOutVertically { height -> -height } + fadeOut() } else { // If the target number is smaller, it slides down and fades in // while the initial number slides down and fades out. slideInVertically { height -> -height } + fadeIn() with slideOutVertically { height -> height } + fadeOut() }.using( // Disable clipping since the faded slide-in/out should // be displayed out of bounds. SizeTransform(clip = false) ) } ) { targetCount -> Text(text = "$targetCount") }
EnterTransition
מגדיר איך תוכן היעד ייראה.
ExitTransition
מגדיר איך התוכן הראשוני צריך להיעלם. כמו כן
לכל הפונקציות של EnterTransition
ו-ExitTransition
שזמינות
AnimatedVisibility
, AnimatedContent
הצעות slideIntoContainer
ו-slideOutOfContainer
.
אלה חלופות נוחות ל-slideInHorizontally/Vertically
ול
הפונקציה slideOutHorizontally/Vertically
שמחשבת את המרחק של השקף על סמך
את גודל התוכן הראשוני ותוכן היעד של
תוכן בAnimatedContent
.
ב-SizeTransform
מוגדר האופן שבו
הגודל צריך להיות הנפשה בין הטקסט הראשוני לתוכן היעד. יש לך
גישה גם לגודל הראשוני וגם לגודל היעד כאשר יוצרים את
אנימציה. SizeTransform
גם קובע אם התוכן ייחתך
בהתאם לגודל הרכיב במהלך אנימציות.
var expanded by remember { mutableStateOf(false) } Surface( color = MaterialTheme.colorScheme.primary, onClick = { expanded = !expanded } ) { AnimatedContent( targetState = expanded, transitionSpec = { fadeIn(animationSpec = tween(150, 150)) with fadeOut(animationSpec = tween(150)) using SizeTransform { initialSize, targetSize -> if (targetState) { keyframes { // Expand horizontally first. IntSize(targetSize.width, initialSize.height) at 150 durationMillis = 300 } } else { keyframes { // Shrink vertically first. IntSize(initialSize.width, targetSize.height) at 150 durationMillis = 300 } } } } ) { targetExpanded -> if (targetExpanded) { Expanded() } else { ContentIcon() } } }
הוספת אנימציה למעברי כניסה ויציאה של ילדים
בדיוק כמו AnimatedVisibility
, גם animateEnterExit
זמין בתוך lambda של תוכן של AnimatedContent
. שימוש בטיוטה הזו
להחיל את EnterAnimation
ואת ExitAnimation
על כל אחד מהנכסים הישירים או העקיפים
לילדים בנפרד.
הוספת אנימציה מותאמת אישית
בדיוק כמו AnimatedVisibility
, השדה transition
זמין
תוכן lambda של AnimatedContent
. אפשר להשתמש בה כדי ליצור אנימציה בהתאמה אישית
את האפקט שפועל בו-זמנית עם המעבר אל AnimatedContent
. צפייה
לפרטים נוספים, אפשר לעדכן את המעבר.
יצירת אנימציה בין שתי פריסות עם Crossfade
Crossfade
יוצרת אנימציה בין שתי פריסות באמצעות אנימציה של עמעום הדרגתי. על ידי החלפת המצב
הערך שמועבר לפרמטר current
, התוכן מוחלף
אנימציה הדרגתית.
var currentPage by remember { mutableStateOf("A") } Crossfade(targetState = currentPage) { screen -> when (screen) { "A" -> Text("Page A") "B" -> Text("Page B") } }
מגבילי אנימציה מובנים
אנימציה של שינויי גודל של תוכן קומפוזבילי עם animateContentSize
![אנימציה של תוכן קומפוזבילי ירוק שמשתנה בצורה חלקה.](https://developer.android.com/static/develop/ui/compose/images/animations/animated_content_size.gif?hl=he)
תכונת הצירוף 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 } ) { }
אנימציות של פריט ברשימה
אם אתם רוצים להוסיף אנימציה לסידור מחדש של פריטים ברשימה או ברשת, כדאי לעיין מסמכי תיעוד של אנימציה של פריט בפריסה מושהית.
מומלץ עבורך
- הערה: טקסט הקישור מוצג כאשר JavaScript מושבת
- אנימציות מבוססות-ערך
- אנימציות בכתיבה
- תמיכה בכלי אנימציה {:#tooling}