ভাগ করা উপাদান সহ নেভিগেশন

চিত্র ১. অভিন্ন উপাদান ব্যবহার করে নেভিগেশন।

শেয়ার্ড এলিমেন্টগুলো একটি ভিজ্যুয়াল সংযোগ তৈরি করে ব্যবহারকারীকে পথ দেখানোর মাধ্যমে স্ক্রিনগুলোর মধ্যে পরিবর্তনকে আরও মসৃণ ও আকর্ষণীয় করে তোলে। এই নির্দেশিকাটিতে নেভিগেশন ৩ এবং নেভিগেশন ২ উভয় জেটপ্যাক লাইব্রেরির সাথে শেয়ার্ড এলিমেন্ট এপিআইগুলো কীভাবে ব্যবহার করতে হয়, তা দেখানো হয়েছে।

নিম্নলিখিত কোড স্নিপেটটিতে 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-এর সাথে শেয়ার্ড এলিমেন্ট এপিআই ব্যবহার করতে হলে, আপনাকে প্রথমে আপনার অ্যাপের 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. অ্যান্ড্রয়েড ১৫ (এপিআই লেভেল ৩৫) বা তার উচ্চতর সংস্করণে চালিত ডিভাইসগুলিতে প্রেডিক্টিভ ব্যাক অ্যানিমেশন ডিফল্টরূপে সক্রিয় থাকে। অ্যান্ড্রয়েড ১৪ (এপিআই লেভেল ৩৪) চালিত ডিভাইসগুলির জন্য, আপনাকে ডেভেলপার অপশন থেকে প্রেডিক্টিভ ব্যাক সেটিংটি চালু করতে হবে।

  3. আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ১৪ বা তার নিম্নতর সংস্করণকে টার্গেট করে, তাহলে আপনাকে অবশ্যই আপনার AndroidManifest.xml ফাইলের <application> অথবা নির্দিষ্ট <activity> এলিমেন্টগুলিতে android:enableOnBackInvokedCallback="true" যোগ করতে হবে। আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ১৫ বা তার উচ্চতর সংস্করণকে টার্গেট করে, তাহলে এই ফ্ল্যাগটির প্রয়োজন নেই।

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
      <application
          ...
          android:enableOnBackInvokedCallback="true">
      </application>
    </manifest>
    
চিত্র ২. ভবিষ্যদ্বাণীমূলক ব্যাক সহ ভাগ করা উপাদানসমূহ।