لتخصيص طريقة تشغيل الرسوم المتحركة للانتقال بين العناصر المشترَكة، هناك بعض المَعلمات التي يمكن استخدامها لتغيير طريقة انتقال العناصر المشترَكة.
مواصفات الصورة المتحركة
لتغيير مواصفات الحركة المستخدَمة في تغيير الحجم والموضع، يمكنك تحديد مَعلمة 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()
إلى منع إعادة التدفق
أثناء زيادة حجمه.
لا |
|
---|---|
المقاطع والصور المركّبة
لكي تتشارك العناصر المشترَكة بين عناصر قابلة للإنشاء مختلفة، يتم رفع مستوى عرض العنصر القابل للإنشاء إلى طبقة تراكب عند بدء الانتقال إلى العنصر المطابق في الوجهة. ويؤدي ذلك إلى خروج العنصر من حدود العنصر الأصل وتجاهل تحويلات الطبقة (مثل الشفافية والحجم).
سيتم عرضه فوق عناصر واجهة المستخدم الأخرى غير المشترَكة. بعد انتهاء عملية النقل، سيتم نقل العنصر من الطبقة المتراكبة إلى 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
أعلى العنصر المشترَك إلى أن تصبح الشاشة غير مرئية. تؤدي إضافة المعدِّل إلى العنصر القابل للإنشاء إلى إبقائه مرتفعًا.
بدون |
مع |
---|---|
قد تريد أن يتم تحريك العنصر القابل للإنشاء غير المشترَك بعيدًا بالإضافة إلى
أن يظل في أعلى العناصر القابلة للإنشاء الأخرى قبل الانتقال. في مثل هذه الحالات، استخدِم
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
. سيؤدي ذلك إلى تكبير العنصر أو تصغيره. وتستجيب جميع العناصر الأخرى في التنسيق لهذا التغيير.
|
(لاحظ كيف تتحرك العناصر الأخرى في القائمة إلى الأسفل استجابةً للعنصر الذي يزداد حجمه) |
---|---|