We use state in ViewModel to keep data safe when the screen changes or the app rotates. It helps the app remember what the user was doing.
State in ViewModel in Android Kotlin
class MyViewModel : ViewModel() {
private val _state = MutableLiveData<String>()
val state: LiveData<String> get() = _state
fun updateState(newValue: String) {
_state.value = newValue
}
}Use MutableLiveData inside ViewModel to hold data that can change.
Expose LiveData to the UI to observe changes without allowing direct modification.
increment() is called.private val _count = MutableLiveData<Int>(0) val count: LiveData<Int> get() = _count fun increment() { _count.value = (_count.value ?: 0) + 1 }
private val _text = MutableLiveData<String>()
val text: LiveData<String> get() = _text
fun setText(newText: String) {
_text.value = newText
}This ViewModel holds a count number. When you press a button, it increases the count. The UI listens to changes and updates the displayed number automatically.
import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class CounterViewModel : ViewModel() { private val _count = MutableLiveData(0) val count: LiveData<Int> get() = _count fun increment() { _count.value = (_count.value ?: 0) + 1 } } // In your Activity or Fragment: // val viewModel = ViewModelProvider(this).get(CounterViewModel::class.java) // viewModel.count.observe(this) { value -> // textView.text = "Count: $value" // } // button.setOnClickListener { viewModel.increment() }
Always keep your UI code separate from data logic by using ViewModel.
LiveData automatically updates the UI when data changes, so you don't have to refresh manually.
Remember to observe LiveData with lifecycle awareness to avoid memory leaks.
State in ViewModel keeps data safe during screen changes.
Use MutableLiveData inside ViewModel and expose LiveData to UI.
UI observes LiveData to update automatically when data changes.
Practice
ViewModel in Android development?Solution
Step 1: Understand ViewModel role and compare options
ViewModel is designed to hold UI data and survive configuration changes like screen rotations. Only To store and manage UI-related data safely during configuration changes correctly describes this purpose; others describe unrelated or incorrect roles.Final Answer:
To store and manage UI-related data safely during configuration changes -> Option CQuick Check:
ViewModel stores UI data safely [OK]
- Thinking ViewModel handles UI events directly
- Assuming ViewModel replaces Activity lifecycle
- Using ViewModel for network calls on main thread
Solution
Step 1: Identify mutable LiveData declaration and syntax
MutableLiveData allows changing the value; LiveData alone is read-only. val data = MutableLiveData<String>() correctly declares a mutable LiveData with type String.Final Answer:
val data = MutableLiveData<String>() -> Option DQuick Check:
MutableLiveData is mutable LiveData [OK]
- Using LiveData() directly (it's abstract)
- Declaring mutable LiveData as var without MutableLiveData
- Casting MutableLiveData to LiveData incorrectly
class MyViewModel : ViewModel() {
private val _count = MutableLiveData(0)
val count: LiveData<Int> = _count
fun increment() {
_count.value = (_count.value ?: 0) + 1
}
}What will be the value of
count after calling increment() twice starting from initial state?Solution
Step 1: Trace execution from initial value
_count starts at 0 as MutableLiveData(0). Each increment adds 1: first call sets 1, second call sets 2.Final Answer:
2 -> Option AQuick Check:
0 + 1 + 1 = 2 [OK]
- Forgetting to unwrap nullable value with ?: 0
- Assuming LiveData updates automatically without setting value
- Confusing private _count with public count
class SampleViewModel : ViewModel() {
val data = MutableLiveData<String>()
fun updateData(newValue: String) {
data.value = newValue
}
fun getData(): String {
return data.value
}
}Solution
Step 1: Analyze getData() return type mismatch
data.value is nullable String?, but getData() returns non-null String. Returning nullable as non-null causes compile error or runtime crash.Final Answer:
getData() returns nullable String but declared as non-null -> Option AQuick Check:
LiveData.value is nullable [OK]
- Ignoring nullable type of LiveData.value
- Thinking postValue() is mandatory for all updates
- Believing ViewModel cannot have functions
Solution
Step 1: Identify correct encapsulation pattern
MutableLiveData should be private; expose only LiveData publicly. private val _state = MutableLiveData<Int>() val state: LiveData<Int> get() = _state declares private MutableLiveData and public LiveData getter correctly.Final Answer:
private val _state = MutableLiveData<Int>()\nval state: LiveData<Int> get() = _state -> Option BQuick Check:
Expose LiveData, keep MutableLiveData private [OK]
- Exposing MutableLiveData publicly
- Declaring LiveData as mutable
- Using LiveData constructor directly (abstract class)
Ready to prove it?
Pass the test and this pattern moves unknown
