عناصر مشترک با ایجاد ارتباط دیداری که کاربر را راهنمایی میکند، گذار بین صفحهها را روانتر و جذابتر میکنند. این راهنما نشان میدهد که چگونه از میاناهای برنامهسازی کاربردی عنصر مشترک با هر دو کتابخانه Jetpack Navigation 3 و Navigation 2 استفاده کنید.
تکه کد زیر شامل DetailsScreen و HomeScreen عناصر ترکیبی است که
بهعنوان مقاصدی که کاربران میتوانند بین آنها پیمایش کنند عمل میکنند. در هر صفحه، از اصلاحگر
sharedElement هم روی تصویر و هم روی نوشتار استفاده میشود تا
هریک از این عناصر بهطور مستقل بین صفحهها پویاسازی شود.
@Composable fun DetailsScreen( id: Int, snack: Snack, sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, onBackPressed: () -> Unit ) { with(sharedTransitionScope) { Column( modifier = Modifier .fillMaxSize() .clickable { onBackPressed() }, ) { Image( painterResource(id = snack.image), contentDescription = snack.description, contentScale = ContentScale.Crop, modifier = Modifier .sharedElement( sharedTransitionScope.rememberSharedContentState(key = "image-$id"), animatedVisibilityScope = animatedVisibilityScope ) .aspectRatio(1f) .fillMaxWidth() ) Text( text = snack.name, fontSize = 18.sp, modifier = Modifier .sharedElement( sharedTransitionScope.rememberSharedContentState(key = "text-$id"), animatedVisibilityScope = animatedVisibilityScope ) .fillMaxWidth(), ) } } } @Composable fun HomeScreen( sharedTransitionScope: SharedTransitionScope, animatedVisibilityScope: AnimatedVisibilityScope, onItemClick: (Int) -> Unit, ) { LazyColumn( modifier = Modifier .fillMaxSize() .padding(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { itemsIndexed(listSnacks) { index, item -> Row( modifier = Modifier .fillMaxWidth() .clickable { onItemClick(index) }, ) { Spacer(modifier = Modifier.width(8.dp)) with(sharedTransitionScope) { Image( painterResource(id = item.image), contentDescription = item.description, contentScale = ContentScale.Crop, modifier = Modifier .sharedElement( sharedTransitionScope.rememberSharedContentState(key = "image-$index"), animatedVisibilityScope = animatedVisibilityScope ) .size(100.dp) ) Spacer(modifier = Modifier.width(8.dp)) Text( item.name, fontSize = 18.sp, modifier = Modifier .align(Alignment.CenterVertically) .sharedElement( sharedTransitionScope.rememberSharedContentState(key = "text-$index"), animatedVisibilityScope = animatedVisibilityScope, ) ) } } } } }
ناوبری ۳
برای استفاده از میاناهای برنامهسازی کاربردی عنصر مشترک با «پیمایش ۳»، ابتدا باید NavDisplay برنامه خود را در SharedTransitionLayout بپیچید. سپس میتوانید
SharedTransitionScope ارائهشده را به عناصر ترکیبی صفحه منتقل کنید.
برای AnimatedVisibilityScope، از ترکیب محلی
LocalNavAnimatedContentScope استفاده کنید که
AnimatedContentScope را از AnimatedContent ارائه میدهد و NavDisplay
بهصورت داخلی برای پویانمایی بین صحنهها استفاده میکند.
@Composable fun SharedElement_Nav3() { SharedTransitionLayout { val backStack = rememberNavBackStack(HomeRoute) // Note: NavDisplay accepts a `sharedTransitionScope` parameter, which is used to animate // NavEntry instances between scenes. This parameter *isn't* required for shared element // or shared bounds transitioning elements between different NavEntry, as demonstrated in // this sample. // See https://developer.android.com/guide/navigation/navigation-3/animate-destinations#transition-nav-entries NavDisplay( modifier = Modifier.safeDrawingPadding(), backStack = backStack, entryProvider = entryProvider { entry<HomeRoute> { HomeScreen( sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = LocalNavAnimatedContentScope.current, onItemClick = { backStack.add(DetailsRoute(it)) }) } entry<DetailsRoute> { detailsRoute -> val id = detailsRoute.item val snack = listSnacks[id] DetailsScreen( id = id, snack = snack, sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = LocalNavAnimatedContentScope.current, onBackPressed = { backStack.removeLastOrNull() }, ) } }) } }
ناوبری ۲
برای استفاده از میاناهای برنامهسازی کاربردی عنصر همرسانیشده با «پیمایش ۲»، ابتدا باید
NavHost برنامه خود را در SharedTransitionLayout بپیچید. سپس میتوانید SharedTransitionScope ارائهشده را به عناصر ترکیبی صفحه منتقل کنید.
پارامتر content سازنده composable از
AnimatedContentScope بهعنوان گیرنده استفاده میکند، بنابراین میتوانید از this@composable برای
ارجاع دادن به آن محدوده استفاده کنید.
@Composable fun SharedElement_Nav2() { SharedTransitionLayout { val navController = rememberNavController() NavHost( navController = navController, startDestination = "home", modifier = Modifier.safeDrawingPadding() ) { composable("home") { HomeScreen( sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = this@composable, onItemClick = { navController.navigate("details/$it") }) } composable( "details/{item}", arguments = listOf(navArgument("item") { type = NavType.IntType }) ) { backStackEntry -> val id = backStackEntry.arguments?.getInt("item") ?: 0 val snack = listSnacks[id] DetailsScreen( id = id, snack = snack, sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = this@composable, onBackPressed = { navController.popBackStack() } ) } } } }
اشاره برگشت پیشگویانه با عناصر همرسانیشده
برای استفاده از بازگشت پیشبینانه با عناصر مشترک، این مراحل را دنبال کنید:
همه نسخههای «پیمایش ۳» از «برگشت پیشگویانه» پشتیبانی میکنند. برای «پیمایش ۲»، از نسخه پخش
2.8.0-alpha02ازnavigation-composeیا جدیدتر استفاده کنید:[versions] androidx-navigation = "2.8.0-alpha02" # Or newer [libraries] androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }dependencies { implementation(libs.androidx.navigation.compose) }پویانماییهای برگشت پیشبین بهطور پیشفرض در دستگاههای دارای Android 15 (میانای برنامه کاربردی سطح ۳۵) یا بالاتر فعال است. برای دستگاههای دارای Android 14 (میانای برنامهسازی کاربردی سطح ۳۴)، باید تنظیم بازگشت پیشبینانه را در گزینههای توسعهدهندگان فعال کنید.
اگر برنامه شما Android 14 یا نسخههای پایینتر را هدفیابی میکند، باید
android:enableOnBackInvokedCallback="true"را به<application>یا عناصر<activity>خاص در فایلAndroidManifest.xmlخود اضافه کنید. اگر برنامه شما Android 15 یا بالاتر را هدفیابی میکند، به این پرچم نیاز ندارید.<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application ... android:enableOnBackInvokedCallback="true"> </application> </manifest>