إضافة تأثيرات متحركة بين الوجهات

توفّر NavDisplay إمكانات رسوم متحركة مدمجة لإنشاء التحولات المرئية السلسة أثناء تنقّل المستخدمين في تطبيقك. ويمكنك تخصيص هذه الرسوم المتحرّكة على مستوى NavDisplay أو على أساس كلNavEntry باستخدام البيانات الوصفية.

إلغاء الانتقالات التلقائية

يستخدم NavDisplay ContentTransform لتحديد كيفية عرض المحتوى المتحرك أثناء التنقّل. يمكنك إلغاء سلوكيات الرسوم المتحركة التلقائية من خلال تقديم مَعلمات انتقال إلى NavDisplay.

  • transitionSpec: تحدِّد هذه المَعلمة ContentTransform المطلوب تطبيقه عند إضافة محتوى إلى الحزمة الخلفية (أي عند الانتقال إلى الأمام).
  • popTransitionSpec: تحدِّد هذه المَعلمة ContentTransform التي يتم تطبيقها عند إزالة المحتوى من حزمة الرجوع (أي عند الانتقال إلى الوراء).
  • predictivePopTransitionSpec: تحدِّد هذه المَعلمة ContentTransform المطلوب تطبيقه عند عرض المحتوى باستخدام لفتة تنبؤية للرجوع.

إلغاء عمليات النقل على مستوى NavEntry الفردي

يمكنك أيضًا تحديد صور متحركة مخصّصة لعناصر NavEntry معيّنة باستخدام بياناتها الوصفية. NavDisplay يتعرّف على مفاتيح البيانات الوصفية الخاصة لتطبيق التحولات الخاصة بكل إدخال:

  • NavDisplay.transitionSpec: استخدِم هذه الدالة المساعِدة لتحديد المؤثر المرئي للتنقّل إلى الأمام.
  • NavDisplay.popTransitionSpec: استخدِم هذه الدالة المساعِدة لتحديد المَعلمات المتعلّقة بالحركة المتحرّكة للتنقّل للخلف في NavEntry معيّن.
  • NavDisplay.predictivePopTransitionSpec: استخدِم هذه الدالة المساعِدة لتحديد المؤثر المرئي لإيماءات الرجوع التوقّعية لNavEntry معيّن.

تلغي عمليات نقل بيانات التعريف هذه لكل إدخال عمليات نقل NavDisplay الشاملة التي تحمل الاسم نفسه.

يوضِّح المقتطف التالي كلّ من عمليات النقل الشاملة NavDisplay وأحد عمليات الإلغاء على مستوى NavEntry الفردي:

@Serializable
data object ScreenA : NavKey

@Serializable
data object ScreenB : NavKey

@Serializable
data object ScreenC : NavKey

class AnimatedNavDisplayActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            Scaffold { paddingValues ->

                val backStack = rememberNavBackStack(ScreenA)

                NavDisplay(
                    backStack = backStack,
                    onBack = { backStack.removeLastOrNull() },
                    entryProvider = entryProvider {
                        entry<ScreenA> {
                            ContentOrange("This is Screen A") {
                                Button(onClick = { backStack.add(ScreenB) }) {
                                    Text("Go to Screen B")
                                }
                            }
                        }
                        entry<ScreenB> {
                            ContentMauve("This is Screen B") {
                                Button(onClick = { backStack.add(ScreenC) }) {
                                    Text("Go to Screen C")
                                }
                            }
                        }
                        entry<ScreenC>(
                            metadata = NavDisplay.transitionSpec {
                                // Slide new content up, keeping the old content in place underneath
                                slideInVertically(
                                    initialOffsetY = { it },
                                    animationSpec = tween(1000)
                                ) togetherWith ExitTransition.KeepUntilTransitionsFinished
                            } + NavDisplay.popTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            } + NavDisplay.predictivePopTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            }
                        ) {
                            ContentGreen("This is Screen C")
                        }
                    },
                    transitionSpec = {
                        // Slide in from right when navigating forward
                        slideInHorizontally(initialOffsetX = { it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { -it })
                    },
                    popTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    predictivePopTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    modifier = Modifier.padding(paddingValues)
                )
            }
        }
    }
}

الشكل 1. تطبيق يتضمّن صورًا متحركة مخصّصة