নিম্নলিখিত বিভাগগুলিতে আপনার ব্যাক স্ট্যাক সংরক্ষণ করার এবং এতে থাকা এন্ট্রিগুলির সাথে সম্পর্কিত স্টেট সংরক্ষণ করার কৌশলগুলি বর্ণনা করা হয়েছে।
আপনার পিঠের স্ট্যাক বাঁচান
কনফিগারেশন পরিবর্তন এবং প্রসেস বন্ধ হয়ে যাওয়াসহ বিভিন্ন লাইফসাইকেল ইভেন্টের পরেও আপনার অ্যাপের নেভিগেশন স্টেট যেন অক্ষুণ্ণ থাকে, তা একটি ভালো ইউজার এক্সপেরিয়েন্সের জন্য অত্যন্ত গুরুত্বপূর্ণ। নেভিগেশন ৩-এ আপনার ব্যাক স্ট্যাকের মালিকানা আপনারই, তাই এটি কীভাবে তৈরি বা সংরক্ষণ করবেন সে বিষয়ে কোনো কঠোর নির্দেশিকা নেই। তবে, নেভিগেশন ৩ একটি সুবিধাজনক পদ্ধতি প্রদান করে যা আপনাকে একটি সংরক্ষণযোগ্য ব্যাক স্ট্যাক দেয়: 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 ব্যবহার করতে, এই ধাপগুলো অনুসরণ করুন:
- আপনার
app/build.gradle.ktsফাইলেandroidx.lifecycle:lifecycle-viewmodel-navigation3ডিপেন্ডেন্সিটি যোগ করুন। - একটি
NavDisplayতৈরি করার সময়entryDecoratorsএর তালিকায় ডিফল্টrememberSaveableStateHolderNavEntryDecorator()যোগ করুন। -
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 { }, )