כדי להתאים אישית את האופן שבו אנימציית המעבר של הרכיב המשותף פועלת, אפשר להשתמש בכמה פרמטרים כדי לשנות את המעבר של הרכיבים המשותפים.
מפרט האנימציה
כדי לשנות את הגדרות האנימציה שמשמשות לתנועת הגודל והמיקום, אפשר לציין פרמטר 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 first: מודד את פריסת הרכיב הצאצא עם אילוצי התצוגה המקדימה (או היעד). לאחר מכן, הפריסה היציבה של רכיב הצאצא מותאמת כך שתתאים לגבולות המשותפים.
אפשר לחשוב על ScaleToBounds כעל 'קנה מידה גרפי' בין המצבים.
לעומת זאת, RemeasureToBounds מודד מחדש את פריסת הצאצא של sharedBounds ומסדר אותה מחדש עם אילוצים קבועים מונפשים על סמך גודל היעד. המדידה מחדש מופעלת על ידי שינוי בגודל הגבולות, שיכול להיות בכל פריים.
לרכיבים הניתנים להרכבה Text, מומלץ להשתמש ב-ScaleToBounds, כי הוא מונע פריסה מחדש של רכיבים וסידור מחדש של טקסט בשורות שונות. מומלץ להשתמש ב-RemeasureToBounds לגבולות עם יחסי גובה-רוחב שונים, ואם רוצים ליצור מעבר חלק בין שני הרכיבים המשותפים.
ההבדל בין שני מצבי השינוי של הגודל מודגם בדוגמאות הבאות:
|
|
|---|---|
דילוג לפריסה הסופית
כברירת מחדל, כשעוברים בין שני פריסות, הגודל של הפריסה מונפש בין מצב ההתחלה למצב הסופי. יכול להיות שזו התנהגות לא רצויה כשמנפישים תוכן כמו טקסט.
בדוגמה הבאה אפשר לראות את טקסט התיאור 'Lorem Ipsum' נכנס למסך בשתי דרכים שונות. בדוגמה הראשונה, הטקסט מתאים את עצמו כשהוא נכנס כשהגודל של הקונטיינר גדל. בדוגמה השנייה, הטקסט לא מסתדר מחדש כשהוא גדל. הוספת Modifier.skipToLookaheadSize() מונעת את השינוי של הפריסה כשהיא גדלה.
אין |
|
|---|---|
קליפים ושכבות-על
כדי שהאלמנטים המשותפים יהיו משותפים בין רכיבי Composable שונים, הרינדור של רכיב ה-Composable מועבר לשכבת-על כשהמעבר מתחיל להתאים ליעד. המשמעות היא שהיא תצא מגבולות ההורה והטרנספורמציות של השכבה (לדוגמה, האלפא והקנה מידה).
הוא יוצג מעל רכיבים אחרים בממשק המשתמש שלא משותפים. בסיום המעבר, הרכיב יוסר מהשכבה העליונה ויוצג בחלון משלו 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 מעל הרכיב המשותף עד שהמסך לא יהיה גלוי. הוספת ה-modifier לרכיב הקומפוזבילי שומרת על ההדגשה שלו.
בלי |
עם |
|---|---|
יכול להיות שתרצו שהרכיב הניתן להרכבה שלא משותף יונפש החוצה וגם יישאר מעל שאר הרכיבים הניתנים להרכבה לפני המעבר. במקרים כאלה, משתמשים ב-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. הפעולה הזו גורמת לפריט לגדול או להתכווץ. כל שאר הפריטים בפריסה מגיבים לשינוי.
|
(שימו לב איך הפריטים האחרים ברשימה זזים למטה בתגובה להתרחבות של הפריט) |
|---|---|