برای سفارشی کردن نحوه اجرای انیمیشن انتقال عناصر مشترک، چند پارامتر وجود دارد که می توان از آنها برای تغییر نحوه انتقال عناصر مشترک استفاده کرد.
مشخصات انیمیشن
برای تغییر مشخصات انیمیشن مورد استفاده برای حرکت اندازه و موقعیت، میتوانید یک پارامتر 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
استفاده می کند.
حالت تغییر اندازه
هنگام متحرک سازی بین دو کران مشترک، می توانید پارامتر resizeMode
را روی RemeasureToBounds
یا ScaleToBounds
تنظیم کنید. این پارامتر نحوه انتقال عنصر مشترک بین دو حالت را تعیین می کند. ScaleToBounds
ابتدا طرح فرزند را با محدودیتهای پیشبینی (یا هدف) اندازهگیری میکند. سپس چیدمان پایدار کودک برای قرار گرفتن در محدوده های مشترک مقیاس می شود. ScaleToBounds
می توان به عنوان یک "مقیاس گرافیکی" بین حالت ها در نظر گرفت.
در حالی که RemeasureToBounds
طرح فرزند sharedBounds
را با محدودیت های متحرک ثابت بر اساس اندازه هدف مجددا اندازه گیری و طرح بندی می کند. اندازهگیری مجدد با تغییر اندازه کرانهها، که به طور بالقوه میتواند هر فریم باشد، آغاز میشود.
برای ترکیببندی Text
، ScaleToBounds
توصیه میشود، زیرا از پخش مجدد و جریان مجدد متن در خطوط مختلف جلوگیری میکند. برای کرانهایی که نسبتهای ابعادی متفاوتی دارند، و اگر میخواهید پیوستگی بین دو عنصر مشترک وجود داشته باشد، RemeasureToBounds
توصیه میشود.
تفاوت بین دو حالت تغییر اندازه را می توان در مثال های زیر مشاهده کرد:
| |
---|---|
به طرح بندی نهایی بروید
به طور پیش فرض، هنگام انتقال بین دو طرح بندی، اندازه طرح بین حالت شروع و نهایی آن متحرک می شود. این ممکن است رفتار نامطلوب در هنگام متحرک سازی محتوایی مانند متن باشد.
مثال زیر متن توضیحات "Lorem Ipsum" را نشان می دهد که به دو روش مختلف وارد صفحه می شود. در مثال اول، متن با وارد شدن با بزرگتر شدن حجم، دوباره جریان می یابد، مثال دوم، متن با بزرگ شدن دوباره جریان پیدا نمی کند. اضافه کردن Modifier.skipToLookaheadSize()
از جریان مجدد با رشد آن جلوگیری می کند.
بدون Modifier.skipToLookahead() - به جریان مجدد متن "Lorem Ipsum" توجه کنید | Modifier.skipToLookahead() - توجه کنید که متن "Lorem Ipsum" وضعیت نهایی خود را در شروع انیمیشن حفظ می کند. |
---|---|
کلیپ و روکش
یک مفهوم مهم هنگام ایجاد عناصر مشترک در Compose این است که برای اینکه آنها بین اجزای سازنده مختلف به اشتراک بگذارند، زمانی که انتقال به تطابق آن در مقصد آغاز می شود ، رندر قابل ترکیب به یک لایه همپوشانی تبدیل می شود . تأثیر این کار این است که از مرزهای والد و تبدیل لایه های آن (به عنوان مثال آلفا و مقیاس) فرار می کند.
این عنصر در بالای سایر عناصر UI غیر مشترک ارائه می شود، پس از پایان انتقال، عنصر از روی همپوشانی به 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()
استفاده میکند.
برای پشتیبانی از حفظ عناصر UI خاص، مانند نوار پایین یا دکمه عمل شناور، همیشه در بالا در طول انتقال عنصر مشترک، از Modifier.renderInSharedTransitionScopeOverlay()
استفاده کنید. بهطور پیشفرض، این اصلاحکننده محتوا را در زمانی که انتقال اشتراکگذاری شده فعال است، در پوشش نگه میدارد.
به عنوان مثال، در Jetsnack، BottomAppBar
باید در بالای عنصر مشترک قرار گیرد تا زمانی که صفحه نمایش قابل مشاهده نباشد. افزودن اصلاح کننده به composable آن را بالا نگه می دارد.
بدون | با |
---|---|
گاهی اوقات شما ممکن است بخواهید که قابلیت ترکیبی غیر اشتراکی شما متحرک شود و همچنین قبل از انتقال در بالای سایر قابل ساختها باقی بماند. در چنین مواردی، از renderInSharedTransitionScopeOverlay().animateEnterExit()
برای متحرک سازی composable به هنگام اجرای انتقال عنصر مشترک استفاده کنید:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
در موارد نادری که میخواهید عنصر اشتراکگذاری شده شما در یک پوشش نمایش داده نشود، میتوانید renderInOverlayDuringTransition
را در sharedElement()
روی false تنظیم کنید.
طرح بندی خواهر و برادر را از تغییرات اندازه عنصر مشترک مطلع کنید
به طور پیشفرض، sharedBounds()
و sharedElement()
به محفظه والد در مورد تغییر اندازه با انتقال طرحبندی اطلاع نمیدهند.
به منظور انتشار تغییرات اندازه در ظرف والد در حین انتقال، پارامتر placeHolderSize
را به PlaceHolderSize.animatedSize
تغییر دهید. انجام این کار باعث رشد یا کوچک شدن آیتم می شود. همه موارد دیگر در طرح به تغییر پاسخ می دهند.
| (توجه کنید که چگونه سایر موارد در لیست در پاسخ به یک مورد در حال رشد به سمت پایین حرکت می کنند) |
---|---|