ভিউমডেল স্কোপিং এপিআই অ্যান্ড্রয়েড জেটপ্যাকের একটি অংশ।
ViewModel কার্যকরভাবে ব্যবহার করার জন্য স্কোপ অত্যন্ত গুরুত্বপূর্ণ। প্রতিটি ViewModel এমন একটি অবজেক্টের স্কোপের মধ্যে থাকে যা ViewModelStoreOwner ইন্টারফেসটি ইমপ্লিমেন্ট করে। এমন বেশ কিছু API রয়েছে যা আপনাকে আপনার ViewModel-গুলোর স্কোপ আরও সহজে পরিচালনা করতে সাহায্য করে। এই ডকুমেন্টটিতে এমন কিছু গুরুত্বপূর্ণ কৌশল তুলে ধরা হয়েছে যা আপনার জানা উচিত।
ViewModelProvider.get() মেথডটি আপনাকে যেকোনো ViewModelStoreOwner স্কোপে থাকা একটি ViewModel-এর ইনস্ট্যান্স পেতে সাহায্য করে। কোটলিন ব্যবহারকারীদের জন্য, সবচেয়ে সাধারণ ব্যবহারের ক্ষেত্রগুলোর জন্য বিভিন্ন এক্সটেনশন ফাংশন উপলব্ধ রয়েছে। সমস্ত কোটলিন এক্সটেনশন ফাংশন ইমপ্লিমেন্টেশন অভ্যন্তরীণভাবে ViewModelProvider API ব্যবহার করে।
নিকটতম ViewModelStoreOwner-এর স্কোপে থাকা ViewModel-গুলো
আপনি একটি ViewModel-কে একটি কম্পোজেবল অ্যাক্টিভিটি, অথবা একটি নেভিগেশন গ্রাফের গন্তব্যের মধ্যে সীমাবদ্ধ করতে পারেন। Compose-এর viewModel() ফাংশনটি আপনাকে নিকটতম ViewModelStoreOwner মধ্যে সীমাবদ্ধ ViewModel-এর একটি ইনস্ট্যান্স পেতে সাহায্য করে।
import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( modifier: Modifier = Modifier, // ViewModel API available in lifecycle.lifecycle-viewmodel-compose // The ViewModel is scoped to the closest ViewModelStoreOwner provided // via the LocalViewModelStoreOwner CompositionLocal. In order of proximity, // this could be the destination of a Navigation graph // or the host Activity. viewModel: MyViewModel = viewModel() ) { /* ... */ }
যেকোনো ViewModelStoreOwner-এর আওতাভুক্ত ViewModel-সমূহ
viewModel() ` ফাংশনটি একটি ঐচ্ছিক viewModelStoreOwner প্যারামিটার গ্রহণ করে, যা ব্যবহার করে আপনি নির্দিষ্ট করতে পারেন যে `ViewModel`-এর ইনস্ট্যান্সটি কোন ` ViewModelStoreOwner আওতাভুক্ত হবে।
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.ViewModelStoreOwner @Composable fun MyScreen( // A custom owner passed in, such as a parent NavBackStackEntry customOwner: ViewModelStoreOwner, // The ViewModel is now scoped to the provided customOwner viewModel: MyViewModel = viewModel(viewModelStoreOwner = customOwner) ) { /* ... */ }
একটি কম্পোজেবল স্কোপের মধ্যে থাকা ভিউমডেল
আপনি rememberViewModelStoreOwner() ব্যবহার করে একটি ViewModel-কে সরাসরি একটি কম্পোজেবলের কল সাইটে স্কোপ করতে পারেন। এটি বিশেষ করে সেইসব UI কম্পোনেন্টের জন্য উপযোগী, যেগুলো স্টেটের উপর ভিত্তি করে ডাইনামিকভাবে স্ক্রিনে যুক্ত বা অপসারিত হয়, যেমন কোনো পেজের আইটেম বা লেজি লিস্ট। যখন ViewModelStoreOwner এর মালিক কম্পোজেবলটি কম্পোজিশন থেকে বেরিয়ে যায়, তখন সংশ্লিষ্ট ViewModelStore খালি হয়ে যায় এবং ViewModel-টি ডেস্ট্রয় হয়ে যায়।
কনফিগারেশন পরিবর্তনের পরেও টিকে থাকে এমন একটি লাইফসাইকেল-সচেতন স্টোর তৈরি করতে rememberViewModelStoreOwner() ব্যবহার করুন।
@Composable
fun RememberViewModelStoreOwnerSample() {
// Create a ViewModelStoreOwner scoped to this specific call site.
// When this composable leaves the composition,
// the associated ViewModelStore will be cleared.
val scopedOwner = rememberViewModelStoreOwner()
CompositionLocalProvider(LocalViewModelStoreOwner provides scopedOwner) {
// This ViewModel is scoped to `scopedOwner`.
// It will survive configuration changes but will be cleared when
// the composable is removed from the UI tree.
val viewModel = viewModel { TestViewModel("scoped_data") }
// Use the ViewModel
}
}
আরও জটিল বাস্তবায়নের জন্য, যেমন একটি HorizontalPager অথবা একাধিক স্বাধীন স্কোপের প্রয়োজন হয় এমন ক্ষেত্রে, rememberViewModelStoreProvider() ব্যবহার করুন। এটি আপনাকে বিভিন্ন কী-এর (যেমন পেজ ইনডেক্স) জন্য স্বতন্ত্র ViewModelStoreOwner ইনস্ট্যান্স তৈরি করতে দেয়। এইভাবে, প্রতিটি পেজ তার নিজস্ব স্বাধীন ViewModel স্টেট বজায় রাখে।
@Composable
fun RememberViewModelStoreProviderSample() {
val storeProvider = rememberViewModelStoreProvider()
val pages = listOf("Page 1", "Page 2", "Page 3")
HorizontalPager(pageCount = pages.size) { page ->
// Create a ViewModelStoreOwner for the specific page using the provider.
val pageOwner = rememberViewModelStoreOwner(provider = storeProvider, key = page)
CompositionLocalProvider(LocalViewModelStoreOwner provides pageOwner) {
val pageViewModel = viewModel { TestViewModel(pages[page]) }
// Use pageViewModel
}
}
}
নেভিগেশন গ্রাফের আওতাভুক্ত ভিউমডেলগুলি
ন্যাভিগেশন গ্রাফগুলোও ViewModel স্টোর ওনার। আপনি যদি ন্যাভিগেশন কম্পোজ ব্যবহার করেন, তাহলে getBackStackEntry() ফাংশনের মাধ্যমে একটি ন্যাভিগেশন গ্রাফের স্কোপে থাকা ViewModel-এর ইনস্ট্যান্স পেতে পারেন।
viewModel() ফাংশনটি LocalViewModelStoreOwner CompositionLocal দ্বারা সরবরাহকৃত নিকটতম ViewModelStoreOwner থেকে ইনস্ট্যান্সটি পুনরুদ্ধার করে। জেটপ্যাক নেভিগেশন ব্যবহারকারী একটি সাধারণ কম্পোজ অ্যাপ্লিকেশনে, এই ওনার হলো বর্তমান নেভিগেশন ব্যাক স্ট্যাক এন্ট্রি। এর মানে হলো, যতক্ষণ পর্যন্ত সেই গন্তব্যটি ব্যাক স্ট্যাকে উপস্থিত থাকে, ততক্ষণ পর্যন্ত ভিউমডেলটি মেমরিতে থাকে।
import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyAppNavHost() { // ... composable("myScreen") { backStackEntry -> // Retrieve the NavBackStackEntry of "parentNavigationRoute" val parentEntry = remember(backStackEntry) { navController.getBackStackEntry("parentNavigationRoute") } // Get the ViewModel scoped to the `parentNavigationRoute` Nav graph val parentViewModel: SharedViewModel = viewModel(parentEntry) // ... } }
আপনি যদি Jetpack Navigation-এর পাশাপাশি Hilt-ও ব্যবহার করেন, তাহলে আপনি hiltNavGraphViewModels(graphId) API-টি নিম্নোক্তভাবে ব্যবহার করতে পারেন।
import androidx.hilt.navigation.compose.hiltViewModel @Composable fun MyAppNavHost() { // ... composable("myScreen") { backStackEntry -> val parentEntry = remember(backStackEntry) { navController.getBackStackEntry("parentNavigationRoute") } // ViewModel API available in hilt.hilt-navigation-compose // The ViewModel is scoped to the `parentNavigationRoute` Navigation graph // and is provided using the Hilt-generated ViewModel factory val parentViewModel: SharedViewModel = hiltViewModel(parentEntry) // ... } }
অতিরিক্ত সম্পদ
ViewModel এবং এর পরিধি সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত উৎসগুলো দেখুন: