নেভিগেশন অবস্থা সংরক্ষণ এবং পরিচালনা করুন

নিম্নলিখিত বিভাগগুলিতে আপনার ব্যাক স্ট্যাক সংরক্ষণ করার এবং এতে থাকা এন্ট্রিগুলির সাথে সম্পর্কিত স্টেট সংরক্ষণ করার কৌশলগুলি বর্ণনা করা হয়েছে।

আপনার পিঠের স্ট্যাক বাঁচান

কনফিগারেশন পরিবর্তন এবং প্রসেস বন্ধ হয়ে যাওয়াসহ বিভিন্ন লাইফসাইকেল ইভেন্টের পরেও আপনার অ্যাপের নেভিগেশন স্টেট যেন অক্ষুণ্ণ থাকে, তা একটি ভালো ইউজার এক্সপেরিয়েন্সের জন্য অত্যন্ত গুরুত্বপূর্ণ। নেভিগেশন ৩-এ আপনার ব্যাক স্ট্যাকের মালিকানা আপনারই, তাই এটি কীভাবে তৈরি বা সংরক্ষণ করবেন সে বিষয়ে কোনো কঠোর নির্দেশিকা নেই। তবে, নেভিগেশন ৩ একটি সুবিধাজনক পদ্ধতি প্রদান করে যা আপনাকে একটি সংরক্ষণযোগ্য ব্যাক স্ট্যাক দেয়: rememberNavBackStack

rememberNavBackStack ব্যবহার করুন

rememberNavBackStack কম্পোজেবল ফাংশনটি এমন একটি ব্যাক স্ট্যাক তৈরি করার জন্য ডিজাইন করা হয়েছে যা কনফিগারেশন পরিবর্তন এবং প্রসেস বন্ধ হয়ে যাওয়ার পরেও টিকে থাকে।

rememberNavBackStack সঠিকভাবে কাজ করার জন্য, আপনার ব্যাক স্ট্যাকের প্রতিটি কী-কে নির্দিষ্ট কিছু শর্ত মেনে চলতে হবে:

  • NavKey ইন্টারফেস ইমপ্লিমেন্ট করুন : ব্যাক স্ট্যাকের প্রতিটি কী-কে অবশ্যই NavKey ইন্টারফেস ইমপ্লিমেন্ট করতে হবে। এটি একটি মার্কার ইন্টারফেস হিসেবে কাজ করে যা লাইব্রেরিকে সংকেত দেয় যে কী-টি সংরক্ষণ করা যেতে পারে।
  • @Serializable অ্যানোটেশনটি ব্যবহার করুন : NavKey ইমপ্লিমেন্ট করার পাশাপাশি, আপনার কী ক্লাস এবং অবজেক্টগুলোকে অবশ্যই @Serializable অ্যানোটেশন দিয়ে চিহ্নিত করতে হবে।

নিম্নলিখিত কোড স্নিপেটটি rememberNavBackStack এর একটি সঠিক বাস্তবায়ন দেখায়:

@Serializable
data object Home : NavKey

@Composable
fun NavBackStack() {
    val backStack = rememberNavBackStack(Home)
}

NavKey এর উপপ্রকার সহ একটি ব্যাক স্ট্যাক মনে রাখবেন।

rememberNavBackStack কম্পোজেবল ফাংশনটি একটি NavBackStack<NavKey> ` রিটার্ন করে। যদি আপনার অ্যাপ NavKey এর নিজস্ব কোনো সাবটাইপ সংজ্ঞায়িত করে, যেখান থেকে এর সমস্ত কী (key) ইনহেরিট করে, তবে আপনি নিম্নলিখিতভাবে একটি কাস্টম `remember` ফাংশন ইমপ্লিমেন্ট করার মাধ্যমে সেই টাইপিংটি সংরক্ষণ করতে পারেন:

@Serializable
sealed interface MyAppNavKey : NavKey

@Serializable
data object ScreenA: MyAppNavKey

@Serializable
data class ScreenB(val id: String): MyAppNavKey

@Composable
fun rememberMyAppNavBackStack(vararg elements: MyAppNavKey): NavBackStack<MyAppNavKey> {
    return rememberSerializable(serializer = serializer()) {
        NavBackStack(*elements)
    }
}

@Composable
fun MyApp() {
    // defaultNavBackStack is NavBackStack<NavKey>
    val defaultNavBackStack = rememberNavBackStack(ScreenA)
    // myAppNavBackStack is NavBackStack<MyAppNavKey>
    val myAppNavBackStack = rememberMyAppNavBackStack(ScreenA)
}

ওপেন পলিমরফিজম কীভাবে পরিচালনা করতে হয় তা সহ আরও উদাহরণের জন্য, NavBackStackSamples দেখুন।

বিকল্প: একটি ViewModel এ সংরক্ষণ করা

আপনার ব্যাক স্ট্যাক পরিচালনা করার আরেকটি উপায় হলো এটিকে একটি ViewModel এ সংরক্ষণ করা। ViewModel বা অন্য কোনো কাস্টম স্টোরেজ ব্যবহার করার সময় প্রসেস বন্ধ হয়ে যাওয়ার পরেও ডেটা অক্ষুণ্ণ রাখার জন্য আপনাকে যা করতে হবে তা হলো:

  • আপনার কী-গুলো যেন সিরিয়ালাইজেবল হয় তা নিশ্চিত করুন : rememberNavBackStack এর মতোই, আপনার ন্যাভিগেশন কী-গুলোও অবশ্যই সিরিয়ালাইজেবল হতে হবে।
  • সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশন ম্যানুয়ালি পরিচালনা করুন : আপনার অ্যাপ ব্যাকগ্রাউন্ডে গেলে বা রিস্টোর করার সময়, প্রতিটি কী-এর সিরিয়ালাইজড রিপ্রেজেন্টেশন পারসিস্টেন্ট স্টোরেজে (যেমন, SharedPreferences , একটি ডেটাবেস বা একটি ফাইল) ম্যানুয়ালি সেভ করা এবং সেখান থেকে ডিসিরিয়ালাইজ করার দায়িত্ব আপনার।

NavEntry তে ViewModel কে স্কোপিং করা

স্ক্রিন ঘোরানোর মতো কনফিগারেশন পরিবর্তনের পরেও UI-সম্পর্কিত স্টেট ধরে রাখতে ViewModels ব্যবহার করা হয়। ডিফল্টরূপে, ViewModels নিকটতম ViewModelStoreOwner স্কোপে থাকে, যা সাধারণত আপনার Activity বা Fragment হয়ে থাকে।

তবে, আপনি হয়তো পুরো Activity পরিবর্তে ব্যাক স্ট্যাকের একটি নির্দিষ্ট NavEntry (অর্থাৎ, একটি নির্দিষ্ট স্ক্রিন বা গন্তব্যে) একটি ViewModel সীমাবদ্ধ করতে চাইতে পারেন। এটি নিশ্চিত করে যে ViewModel স্টেট শুধুমাত্র ততক্ষণই সংরক্ষিত থাকে যতক্ষণ সেই নির্দিষ্ট NavEntry ব্যাক স্ট্যাকের অংশ থাকে, এবং NavEntry পপ হয়ে গেলে তা মুছে যায়।

androidx.lifecycle:lifecycle-viewmodel-navigation3 অ্যাড-অন লাইব্রেরিটি একটি NavEntryDecorator প্রদান করে যা এই কাজটি সহজ করে তোলে। এই ডেকোরেটরটি প্রতিটি NavEntry জন্য একটি ViewModelStoreOwner প্রদান করে। যখন আপনি একটি NavEntry এর কন্টেন্টের ভিতরে একটি ViewModel তৈরি করেন (যেমন, Compose-এ viewModel() ব্যবহার করে), তখন এটি স্বয়ংক্রিয়ভাবে ব্যাক স্ট্যাকে সেই নির্দিষ্ট NavEntry এর কী-এর মধ্যে সীমাবদ্ধ হয়ে যায়। এর মানে হলো, যখন NavEntry ব্যাক স্ট্যাকে যুক্ত করা হয় তখন ViewModel তৈরি হয়, এবং যখন এটি সরানো হয় তখন তা মুছে যায়।

ViewModel কে NavEntry এর আওতায় আনার জন্য NavEntryDecorator ব্যবহার করতে, এই ধাপগুলো অনুসরণ করুন:

  1. আপনার app/build.gradle.kts ফাইলে androidx.lifecycle:lifecycle-viewmodel-navigation3 ডিপেন্ডেন্সিটি যোগ করুন।
  2. একটি NavDisplay তৈরি করার সময় entryDecorators এর তালিকায় ডিফল্ট rememberSaveableStateHolderNavEntryDecorator() যোগ করুন।
  3. entryDecorators এর তালিকায় rememberViewModelStoreNavEntryDecorator() যোগ করুন।

NavDisplay(
    entryDecorators = listOf(
        // Add the default decorators for managing scenes and saving state
        rememberSaveableStateHolderNavEntryDecorator(),
        // Then add the view model store decorator
        rememberViewModelStoreNavEntryDecorator()
    ),
    backStack = backStack,
    entryProvider = entryProvider { },
)