Paylaşılan öğeler, kullanıcıya yol gösteren görsel bir bağlantı oluşturarak ekranlar arasındaki geçişleri daha akıcı ve ilgi çekici hale getirir. Bu kılavuzda, paylaşılan öğe API'lerinin hem Navigation 3 hem de Navigation 2 Jetpack kitaplıklarıyla nasıl kullanılacağı gösterilmektedir.
Aşağıdaki snippet, kullanıcıların arasında gezinebileceği hedefler olarak işlev gören DetailsScreen ve HomeScreen composable'larını içerir. Her ekranda, hem resimde hem de metinde sharedElement değiştiricisi kullanılır. Böylece bu öğelerin her biri, ekranlar arasında bağımsız olarak animasyonlu hale gelir.
@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, ) ) } } } } }
Navigasyon 3
Paylaşılan öğe API'lerini Navigation 3 ile kullanmak için öncelikle uygulamanızın NavDisplay öğesini SharedTransitionLayout içine sarmalamanız gerekir. Daha sonra sağlanan SharedTransitionScope öğesini ekran composable'larına iletebilirsiniz.
AnimatedVisibilityScope için NavDisplay sahneler arasında animasyon oluşturmak üzere dahili olarak kullanılan AnimatedContent'den AnimatedContentScope sağlayan LocalNavAnimatedContentScope kompozisyon yerelini kullanın.
@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() }, ) } }) } }
Gezinme 2
Paylaşılan öğe API'lerini Navigation 2 ile kullanmak için öncelikle uygulamanızın NavHost öğesini SharedTransitionLayout içine sarmalamanız gerekir. Ardından, sağlanan SharedTransitionScope öğesini ekran composable'larına iletebilirsiniz.
composable oluşturucusunun content parametresi alıcı olarak AnimatedContentScope kullandığından bu kapsama referans vermek için this@composable kullanabilirsiniz.
@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() } ) } } } }
Paylaşılan öğelerle tahmin edilen geri gitme
Paylaşılan öğelerle tahmin edilen geri gitme özelliğini kullanmak için aşağıdaki adımları uygulayın:
Navigation 3'ün tüm sürümleri, tahmin edilen geri gitme özelliğini destekler. Navigation 2 için
navigation-compose'nin2.8.0-alpha02sürümünü veya daha yeni bir sürümünü kullanın:[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) }Tahmin edilen geri gitme animasyonları, Android 15 (API düzeyi 35) veya sonraki sürümlerin yüklü olduğu cihazlarda varsayılan olarak etkindir. Android 14 (API düzeyi 34) çalıştıran cihazlarda, geliştirici seçeneklerinde Tahmin edilen geri gitme ayarını etkinleştirmeniz gerekir.
Uygulamanız Android 14 veya önceki sürümleri hedefliyorsa
android:enableOnBackInvokedCallback="true"dosyanızdaki<application>veya belirli<activity>öğelerineAndroidManifest.xmleklemeniz gerekir. Uygulamanız Android 15 veya sonraki sürümleri hedefliyorsa bu işarete ihtiyacınız yoktur.<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application ... android:enableOnBackInvokedCallback="true"> </application> </manifest>