تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
لاستخدام العناصر المشترَكة مع navigation-compose dependency، استخدِم Modifier.sharedElement() الذي يأخذ AnimatedVisibilityScope كمَعلمة. يمكنك استخدام هذه الميزة لتحديد ما يجب أن يكون مرئيًا ومتى.
الشكل 1. Navigation Compose with shared elements.
في ما يلي مثال على استخدام navigation-compose مع العناصر المشترَكة:
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-08-27 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-08-27 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["To use shared elements with the [`navigation-compose` dependency](/jetpack/compose/navigation), use the\n`Modifier.sharedElement()` that takes an `AnimatedVisibilityScope` as a\nparameter. You can use this to decide what should be visible and when.\n**Figure 1.** Navigation Compose with shared elements.\n\nThe following is an example of using `navigation-compose` with shared elements:\n\n\n```kotlin\n@Preview\n@Composable\nfun SharedElement_PredictiveBack() {\n SharedTransitionLayout {\n val navController = rememberNavController()\n NavHost(\n navController = navController,\n startDestination = \"home\"\n ) {\n composable(\"home\") {\n HomeScreen(\n this@SharedTransitionLayout,\n this@composable,\n { navController.navigate(\"details/$it\") }\n )\n }\n composable(\n \"details/{item}\",\n arguments = listOf(navArgument(\"item\") { type = NavType.IntType })\n ) { backStackEntry -\u003e\n val id = backStackEntry.arguments?.getInt(\"item\")\n val snack = listSnacks[id!!]\n DetailsScreen(\n id,\n snack,\n this@SharedTransitionLayout,\n this@composable,\n {\n navController.navigate(\"home\")\n }\n )\n }\n }\n }\n}\n\n@Composable\nfun DetailsScreen(\n id: Int,\n snack: Snack,\n sharedTransitionScope: SharedTransitionScope,\n animatedContentScope: AnimatedContentScope,\n onBackPressed: () -\u003e Unit\n) {\n with(sharedTransitionScope) {\n Column(\n Modifier\n .fillMaxSize()\n .clickable {\n onBackPressed()\n }\n ) {\n Image(\n painterResource(id = snack.image),\n contentDescription = snack.description,\n contentScale = ContentScale.Crop,\n modifier = Modifier\n .sharedElement(\n sharedTransitionScope.rememberSharedContentState(key = \"image-$id\"),\n animatedVisibilityScope = animatedContentScope\n )\n .aspectRatio(1f)\n .fillMaxWidth()\n )\n Text(\n snack.name, fontSize = 18.sp,\n modifier =\n Modifier\n .sharedElement(\n sharedTransitionScope.rememberSharedContentState(key = \"text-$id\"),\n animatedVisibilityScope = animatedContentScope\n )\n .fillMaxWidth()\n )\n }\n }\n}\n\n@Composable\nfun HomeScreen(\n sharedTransitionScope: SharedTransitionScope,\n animatedContentScope: AnimatedContentScope,\n onItemClick: (Int) -\u003e Unit,\n) {\n LazyColumn(\n modifier = Modifier\n .fillMaxSize()\n .padding(8.dp),\n verticalArrangement = Arrangement.spacedBy(8.dp)\n ) {\n itemsIndexed(listSnacks) { index, item -\u003e\n Row(\n Modifier.clickable {\n onItemClick(index)\n }\n ) {\n Spacer(modifier = Modifier.width(8.dp))\n with(sharedTransitionScope) {\n Image(\n painterResource(id = item.image),\n contentDescription = item.description,\n contentScale = ContentScale.Crop,\n modifier = Modifier\n .sharedElement(\n sharedTransitionScope.rememberSharedContentState(key = \"image-$index\"),\n animatedVisibilityScope = animatedContentScope\n )\n .size(100.dp)\n )\n Spacer(modifier = Modifier.width(8.dp))\n Text(\n item.name, fontSize = 18.sp,\n modifier = Modifier\n .align(Alignment.CenterVertically)\n .sharedElement(\n sharedTransitionScope.rememberSharedContentState(key = \"text-$index\"),\n animatedVisibilityScope = animatedContentScope,\n )\n )\n }\n }\n }\n }\n}\n\ndata class Snack(\n val name: String,\n val description: String,\n @DrawableRes val image: Int\n)https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/animations/sharedelement/SharedElementsWithNavigationSnippets.kt#L66-L195\n```\n\n\u003cbr /\u003e\n\nPredictive back with shared elements\n\nTo use [predictive back](/guide/navigation/custom-back/predictive-back-gesture) with shared elements, follow these steps:\n\n1. Use the latest [`navigation-compose` dependency](/develop/ui/compose/navigation), using the snippet from\n the preceding section.\n\n dependencies {\n def nav_version = \"2.8.0-beta02\"\n\n implementation \"androidx.navigation:navigation-compose:$nav_version\"\n }\n\n2. Enable the [Predictive back setting](/guide/navigation/custom-back/predictive-back-gesture#dev-option) in developer options.\n\n3. Add `android:enableOnBackInvokedCallback=\"true\"` to your `AndroidManifest.xml`\n file:\n\n \u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n \u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n \u003cuses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" /\u003e\n \u003cuses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"\n android:maxSdkVersion=\"28\" /\u003e\n\n \u003capplication\n android:allowBackup=\"true\"\n android:icon=\"@mipmap/ic_launcher\"\n android:label=\"@string/app_name\"\n android:roundIcon=\"@mipmap/ic_launcher_round\"\n android:supportsRtl=\"true\"\n android:enableOnBackInvokedCallback=\"true\"\n android:theme=\"@style/Theme.Snippets\"\u003e\n\n**Figure 2.** Navigation Compose with predictive back."]]