ViewModel की खास जानकारी (व्यू)

कॉन्सेप्ट और Jetpack Compose का लागू होना

The ViewModel क्लास, कारोबारी नियम या स्क्रीन लेवल का स्टेट होल्डर है. यह यूज़र इंटरफ़ेस (यूआई) को स्टेट दिखाता है और इससे जुड़े कारोबारी नियम को एनकैप्सुलेट करता है. इसका मुख्य फ़ायदा यह है कि यह स्टेट को कैश करता है और कॉन्फ़िगरेशन में बदलाव होने पर भी उसे सेव रखता है. इसका मतलब है कि ऐक्टिविटी के बीच नेविगेट करने या कॉन्फ़िगरेशन में बदलाव होने पर, आपके यूज़र इंटरफ़ेस (यूआई) को डेटा फिर से फ़ेच नहीं करना पड़ता. जैसे, स्क्रीन को घुमाने पर.

ViewModel के फ़ायदे

ViewModel के बजाय, एक सामान्य क्लास का इस्तेमाल किया जा सकता है. इसमें वह डेटा होता है जो आपके यूज़र इंटरफ़ेस (यूआई) में दिखता है. ऐक्टिविटी या नेविगेशन डेस्टिनेशन के बीच नेविगेट करते समय, यह समस्या बन सकती है. अगर सेव की गई इंस्टेंस स्टेट के तरीके का इस्तेमाल करके डेटा सेव नहीं किया जाता है, तो वह डेटा मिट जाता है. ViewModel, डेटा को सेव रखने के लिए एक आसान एपीआई उपलब्ध कराता है. इससे यह समस्या हल हो जाती है.

ViewModel क्लास के दो मुख्य फ़ायदे हैं:

  • इससे यूज़र इंटरफ़ेस (यूआई) की स्थिति को सेव रखा जा सकता है.
  • इससे कारोबारी नियम का ऐक्सेस मिलता है.

दायरा

ViewModel को इंस्टैंशिएट करते समय, उसे एक ऐसा ऑब्जेक्ट पास किया जाता है जो ViewModelStoreOwner इंटरफ़ेस को लागू करता है. यह नेविगेशन डेस्टिनेशन, नेविगेशन ग्राफ़, ऐक्टिविटी, फ़्रैगमेंट या कोई अन्य टाइप हो सकता है जो इंटरफ़ेस को लागू करता है. इसके बाद, आपका ViewModel, Lifecycle के ViewModelStoreOwner दायरे में आ जाता है. यह तब तक मेमोरी में सेव रहता है, जब तक इसका ViewModelStoreOwner हमेशा के लिए बंद नहीं हो जाता.

कई क्लास, ViewModelStoreOwner इंटरफ़ेस की डायरेक्ट या इनडायरेक्ट सबक्लास होती हैं. डायरेक्ट सबक्लास, ComponentActivity, Fragment, और NavBackStackEntry हैं. इनडायरेक्ट सबक्लास की पूरी सूची देखने के लिए, ViewModelStoreOwner रेफ़रंस देखें.

ViewModel लागू करना

यहां एक ऐसी स्क्रीन के लिए ViewModel को लागू करने का उदाहरण दिया गया है जिससे उपयोगकर्ता पासा रोल कर सकता है.

Kotlin

data class DiceUiState(
    val firstDieValue: Int? = null,
    val secondDieValue: Int? = null,
    val numberOfRolls: Int = 0,
)

class DiceRollViewModel : ViewModel() {

    // Expose screen UI state
    private val _uiState = MutableStateFlow(DiceUiState())
    val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()

    // Handle business logic
    fun rollDice() {
        _uiState.update { currentState ->
            currentState.copy(
                firstDieValue = Random.nextInt(from = 1, until = 7),
                secondDieValue = Random.nextInt(from = 1, until = 7),
                numberOfRolls = currentState.numberOfRolls + 1,
            )
        }
    }
}

Java

public class DiceUiState {
    private final Integer firstDieValue;
    private final Integer secondDieValue;
    private final int numberOfRolls;

    // ...
}

public class DiceRollViewModel extends ViewModel {

    private final MutableLiveData<DiceUiState> uiState =
        new MutableLiveData(new DiceUiState(null, null, 0));
    public LiveData<DiceUiState> getUiState() {
        return uiState;
    }

    public void rollDice() {
        Random random = new Random();
        uiState.setValue(
            new DiceUiState(
                random.nextInt(7) + 1,
                random.nextInt(7) + 1,
                uiState.getValue().getNumberOfRolls() + 1
            )
        );
    }
}

इसके बाद, किसी ऐक्टिविटी से ViewModel को इस तरह ऐक्सेस किया जा सकता है:

Kotlin

import androidx.activity.viewModels

class DiceRollActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same DiceRollViewModel instance created by the first activity.

        // Use the 'by viewModels()' Kotlin property delegate
        // from the activity-ktx artifact
        val viewModel: DiceRollViewModel by viewModels()
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect {
                    // Update UI elements
                }
            }
        }
    }
}

Java

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.
        DiceRollViewModel model = new ViewModelProvider(this).get(DiceRollViewModel.class);
        model.getUiState().observe(this, uiState -> {
            // update UI
        });
    }
}