শেয়ার করা এলিমেন্ট ব্যবহার করে নেভিগেশন

ছবি ১. শেয়ার করা এলিমেন্ট ব্যবহার করে নেভিগেট করা।

শেয়ার করা এলিমেন্ট, স্ক্রিনের মধ্যে ট্রানজিশনকে আরও মসৃণ ও এনগেজিং করে তোলে। এটি ব্যবহারকারীকে গাইড করার জন্য একটি ভিজ্যুয়াল কানেকশন তৈরি করে। এই গাইড দেখায় যে কীভাবে Navigation 3 ও Navigation 2 Jetpack লাইব্রেরির সাথে শেয়ার করা এলিমেন্ট API ব্যবহার করতে হয়।

নিচে দেওয়া স্নিপেটে 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,
                            )
                    )
                }
            }
        }
    }
}

Navigation 3-এর সাথে শেয়ার করা এলিমেন্ট API ব্যবহার করতে, আপনাকে প্রথমে অ্যাপের NavDisplay-কে SharedTransitionLayout-এর মধ্যে র‍্যাপ করতে হবে। তারপরে, আপনি স্ক্রিন কম্পোজেবলগুলিতে প্রদান করা SharedTransitionScope পাস করতে পারবেন।

AnimatedVisibilityScope-এর জন্য, LocalNavAnimatedContentScope কম্পোজিশন লোকাল ব্যবহার করুন যা AnimatedContent থেকে AnimatedContentScope প্রদান করে যা 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()
                        },
                    )
                }
            })
    }
}

Navigation 2-এর সাথে শেয়ার করা এলিমেন্ট API ব্যবহার করতে, আপনাকে প্রথমে নিজের অ্যাপের NavHost SharedTransitionLayout-এর মধ্যে র‍্যাপ করতে হবে। তারপরে, আপনি স্ক্রিন কম্পোজেবলগুলিতে SharedTransitionScope প্রদান করতে পারবেন।

composable বিল্ডারের content প্যারামিটার 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()
                    }
                )
            }
        }
    }
}

শেয়ার করা এলিমেন্ট সহ 'আগের ধাপে ফিরে যাওয়া' সংক্রান্ত পূর্বাভাস

শেয়ার করা এলিমেন্টের সাথে প্রেডিক্টিভ ব্যাক ব্যবহার করতে, এইসব ধাপ অনুসরণ করুন:

  1. Navigation 3-এর সব ভার্সনে 'প্রেডিক্টিভ ব্যাক' ফিচার কাজ করে। Navigation 2-এর জন্য, navigation-compose-এর 2.8.0-alpha02 রিলিজ বা এর পরের যেকোনও ভার্সন ব্যবহার করুন:

    [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)
    }
    
  2. Android 15 (API লেভেল ৩৫) বা তার পরের যেকোনও ভার্সনে চলে এমন ডিভাইসে ডিফল্ট হিসেবে 'প্রেডিক্টিভ ব্যাক' অ্যানিমেশন চালু থাকে। Android 14 (API লেভেল 34) ভার্সনে চলে এমন ডিভাইসের জন্য, ডেভেলপার বিকল্পে আপনাকে অনুমানমূলক ব্যাক সেটিং চালু করতে হবে।

  3. আপনার অ্যাপ Android 14 বা এর আগের যেকোনও ভার্সনকে টার্গেট করলে, আপনাকে অবশ্যই <application> বা নির্দিষ্ট <activity> এলিমেন্টে android:enableOnBackInvokedCallback="true" যোগ করতে হবে।AndroidManifest.xml আপনার অ্যাপ Android 15 বা তার পরবর্তী যেকোনও ভার্সনকে টার্গেট করলে, আপনার এই ফ্ল্যাগ প্রয়োজন হবে না।

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
      <application
          ...
          android:enableOnBackInvokedCallback="true">
      </application>
    </manifest>
    
ছবি ২. 'আগের ধাপে ফিরে যাওয়া' ফিচারের সাথে শেয়ার করা এলিমেন্ট।