כדי להתאים אישית את האופן שבו אנימציית המעבר של הרכיבים המשותפים פועלת, יש מספר פרמטרים שאפשר להשתמש בהם כדי לשנות את אופן המעבר של הרכיבים המשותפים.
מפרט אנימציה
כדי לשנות את מפרט האנימציה שמשמש לתנועה של הגודל והמיקום, אפשר לציין פרמטר boundsTransform
שונה ב-Modifier.sharedElement()
.
כך מקבלים את המיקום הראשוני Rect
ואת מיקום היעד Rect
.
למשל, כדי שהטקסט שבדוגמה הקודמת יזוז עם קשת
תנועה, מציינים את הפרמטר boundsTransform
כדי להשתמש במפרט keyframes
:
val textBoundsTransform = BoundsTransform { initialBounds, targetBounds -> keyframes { durationMillis = boundsAnimationDurationMillis initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing targetBounds at boundsAnimationDurationMillis } } Text( "Cupcake", fontSize = 28.sp, modifier = Modifier.sharedBounds( rememberSharedContentState(key = "title"), animatedVisibilityScope = animatedVisibilityScope, boundsTransform = textBoundsTransform ) )
אפשר להשתמש בכל AnimationSpec
. בדוגמה הזו נעשה שימוש במפרט keyframes
.
boundsTransform
מצב שינוי גודל
כשאתם יוצרים אנימציה בין שני גבולות משותפים, אתם יכולים להגדיר את הפרמטר resizeMode
לערך RemeasureToBounds
או לערך ScaleToBounds
. הפרמטר הזה קובע איך
הרכיב המשותף עובר בין שני המצבים. ScaleToBounds
קודם
מודדת את פריסת הצאצא עם מגבלות המבט לאחור (או היעד). לאחר מכן
הפריסה היציבה של הילד או הילדה מותאמת לגבולות המשותפים.
אפשר לחשוב על ScaleToBounds
כ'סולם גרפי' בין המצבים.
לעומת זאת, RemeasureToBounds
מודד מחדש את הפריסה של הצאצא של sharedBounds
ומבצע לה פריסה מחדש עם אילוצים קבועים מונפשים על סמך גודל היעד.
ולמדידה מחדש יש שינוי בגודל הגבולות, שעלול
בכל פריים.
לחומרים קומפוזביליים של Text
מומלץ להשתמש ב-ScaleToBounds
כי הם ימנעו העברה
והזרמה של טקסט לשורות שונות. אם רוצים רצף חלק בין שני הרכיבים המשותפים, מומלץ להשתמש ב-RemeasureToBounds
כשהגבולות הם ביחסי גובה-רוחב שונים.
אפשר לראות את ההבדל בין שני מצבי הגודל בדוגמאות הבאות:
|
|
---|---|
דילוג לפריסה הסופית
כברירת מחדל, כשעוברים בין שני פריסות, גודל הפריסה משתנה באנימציה בין המצב ההתחלתי למצב הסופי. יכול להיות שזו התנהגות לא רצויה כשמפעילים אנימציה לתוכן כמו טקסט.
הדוגמה הבאה ממחישה את טקסט התיאור "Lorem Ipsum" כניסה
את המסך בשתי דרכים שונות. הדוגמה הראשונה שבה הטקסט זורם מחדש כפי שהוא
נכנס ככל שהמאגר גדל, והדוגמה השנייה לטקסט לא
הזרמה חוזרת כשזה גדל. הוספת Modifier.skipToLookaheadSize()
מונעת את הצורך בזרימה מחדש כשהטקסט מתארך.
No Modifier.skipToLookahead() - שימו לב ל-"Lorem Ipsum" הזרמה חוזרת של טקסט |
Modifier.skipToLookahead() – שימו לב ל-"Lorem Ipsum" הטקסט נשמר במצב הסופי בתחילת האנימציה |
---|---|
קליפים ושכבות-על
אחד הקונספטים החשובים כשיוצרים רכיבים משותפים ב'כתיבה' הוא שכדי להם לשתף בין תכנים קומפוזביליים שונים, הרינדור של תוכן קומפוזבילי מועלה לשכבת-על של שכבה כשהמעבר מתחיל את ההתאמה שלו ביעד. כתוצאה מכך, הוא ימחק את את הגבולות של ההורה ואת הטרנספורמציות בשכבה שלו (לדוגמה אלפא וקנה מידה).
הוא יוצג מעל רכיבים אחרים בממשק המשתמש שאינם משותפים, ברגע שהמעבר
הסתיים, הרכיב יוסר משכבת-העל אל DrawScope
משלו.
כדי לחתוך רכיב משותף לצורה, משתמשים בפונקציה הרגילה Modifier.clip()
. צריך להוסיף אותו אחרי ה-sharedElement()
:
Image( painter = painterResource(id = R.drawable.cupcake), contentDescription = "Cupcake", modifier = Modifier .size(100.dp) .sharedElement( rememberSharedContentState(key = "image"), animatedVisibilityScope = this@AnimatedContent ) .clip(RoundedCornerShape(16.dp)), contentScale = ContentScale.Crop )
אם אתם רוצים לוודא שרכיב משותף אף פעם לא יופיע מחוץ לקונטיינר הורה, תוכלו להגדיר את clipInOverlayDuringTransition
ב-sharedElement()
. כברירת מחדל, למסגרות משותפות בתצוגת עץ, clipInOverlayDuringTransition
משתמש בנתיב של הקליפ מהרכיב ההורה sharedBounds()
.
כדי לתמוך ברכיבים ספציפיים של ממשק המשתמש, כמו סרגל תחתון או לחצן פעולה צף, כך שהם תמיד יופיעו בחלק העליון במהלך מעבר של אלמנט משותף, צריך להשתמש ב-Modifier.renderInSharedTransitionScopeOverlay()
. כברירת מחדל, המשתנה הזה שומר את התוכן בשכבת-העל בזמן שהמעבר המשותף פעיל.
לדוגמה, ב-Jetsnack, צריך להציב את BottomAppBar
מעל הרכיב המשותף עד שהמסך לא יהיה גלוי. הוספת המשתנה למרכיב ה-Composable שומרת עליו במקום גבוה.
בלי |
עם |
---|---|
לפעמים כדאי להציג אנימציה של רכיב ה-Composable שאינו משותף, וגם להשאיר אותו מעל שאר רכיבי ה-Composable לפני המעבר. במקרים כאלה, צריך להשתמש
renderInSharedTransitionScopeOverlay().animateEnterExit()
כדי להוסיף אנימציה
קומפוזביליות כשמעבר הרכיב המשותף פועל:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
במקרים נדירים שבהם רוצים שהרכיב המשותף לא יוצג כשכבת-על, אפשר להגדיר את הערך של renderInOverlayDuringTransition
ב-sharedElement()
כ-false.
שליחת הודעה לפריסות אחות על שינויים בגודל הרכיב המשותף
כברירת מחדל, sharedBounds()
וגם sharedElement()
לא שולחים הודעות להורה
מכל גודל שהוא משתנה ככל שהפריסה עוברת.
כדי להעביר שינויים בגודל לקונטיינר ההורה במהלך המעבר, צריך לשנות את הפרמטר placeHolderSize
ל-PlaceHolderSize.animatedSize
. הפעולה הזו תגרום לפריט לגדול או להתכווץ. כל שאר הפריטים בפריסה מגיבים ל
את השינוי.
|
(שים לב איך הפריטים האחרים ברשימה יורדים בתגובה לפריט אחד שגדל) |
---|---|