ViewModel Scoping APIs   Android Jetpack-এর অংশ।

ViewModel কার্যকরভাবে ব্যবহার করার জন্য স্কোপ হল মূল চাবিকাঠি। প্রতিটি ViewModel এমন একটি অবজেক্টের জন্য স্কোপ করা হয় যা ViewModelStoreOwner ইন্টারফেস প্রয়োগ করে। এমন অনেক API আছে যা আপনাকে আরও সহজে আপনার ViewModel-এর স্কোপ ম্যানেজ করতে দেয়। এই ডকুমেন্টে কিছু গুরুত্বপূর্ণ টেকনিকের ব্যাপারে বলা হয়েছে যেগুলি আপনার জানা উচিত।

ViewModelProvider.get() পদ্ধতি আপনাকে যেকোনও ViewModelStoreOwner-এ স্কোপ করা ViewModel-এর ইনস্ট্যান্স পেতে দেয়। Kotlin ব্যবহারকারীদের জন্য, সবচেয়ে সাধারণ ব্যবহারের ক্ষেত্রে বিভিন্ন এক্সটেনশন ফাংশন উপলভ্য। সব Kotlin এক্সটেনশন ফাংশন ইমপ্লিমেন্টেশন ViewModelProvider API ব্যবহার করে।

সবচেয়ে কাছের ViewModelStoreOwner-এ ViewModel স্কোপ করা

আপনি ViewModel-কে কম্পোজেবল, অ্যাক্টিভিটি বা নেভিগেশন গ্রাফের গন্তব্যে স্কোপ করতে পারবেন। Compose-এ viewModel() ফাংশন আপনাকে ViewModel-এর একটি ইনস্ট্যান্স পেতে দেয় যা সবচেয়ে কাছের ViewModelStoreOwner-এ স্কোপ করা থাকে।

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)
) {
    /* ... */
}

কম্পোজেবল-এ স্কোপ করা ViewModel

আপনি 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

নেভিগেশন গ্রাফও ViewModel স্টোরের মালিক। আপনি Navigation Compose ব্যবহার করলে, getBackStackEntry() ফাংশনের মাধ্যমে Navigation গ্রাফে স্কোপ করা ViewModel-এর ইনস্ট্যান্স পেতে পারেন।

viewModel(), LocalViewModelStoreOwner CompositionLocal-এর মাধ্যমে প্রদান করা নিকটতম ViewModelStoreOwner থেকে ইনস্ট্যান্স ফিরিয়ে আনে। Jetpack Navigation ব্যবহার করে Compose অ্যাপ্লিকেশনে, এই মালিক হলেন বর্তমান Navigation ব্যাক স্ট্যাক এন্ট্রি। এর অর্থ হল, যতক্ষণ পর্যন্ত সেই ডেস্টিনেশন ব্যাক স্ট্যাকে উপস্থিত থাকে, ততক্ষণ ViewModel মেমরিতে থাকে।

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)
        // ...
    }
}

অতিরিক্ত রিসোর্স

ViewModels ও স্কোপ সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন:

ডকুমেন্টেশন

কন্টেন্ট দেখে