[Android] ViewModel-SavedState-ktx 2.2.0 Released
# What is ViewModel-SavedState-ktx
ViewModel-SavedState-ktx is a library that allows you to easily use SavedStateHandle of ViewModel-SavedState by Delegated Property.
# What is ViewModel-SavedState
Up to now, UI states is usually stored in onSavedInstanceState
and restored in onCreate
. From now on, you can store and restore UI states by SavedStateHandle using ViewModel-SavedState.
# Why use ViewModel-SavedState
ViewModel has been kept alive when configuration changes occurred, but ViewModel has been destroyed when Activity killed by OS. By using ViewModel-SavedState, ViewModel save its property when Activity killed by OS.
# How to use ViewModel-SavedState
## How to get SavedStateHandle
- You can get a SavedStateHandle instance via ViewModel’s constructor.
## How to pass SavedStateHandle to ViewModel constructor
- If you call
by viewModels()
in Activity or Fragment,SavedStateHandle
is automatically passed. Theintent.extra
orarguments
is passed automatically toSavedStateHandle
. - If you want to pass parameters other than
SavedStateHandle
orApplication, SavedStateHandle
into ViewModel's constructor, you pass a ViewModel's factory intoby viewModels
. The ViewModel’s factory needs to extendAbstractSavedStateViewModelFactory
. Theintent.extra
orarguments
needs to pass manually to the ViewModel's factory if need it.
## How to use SavedStateHandle
- You can use a value by
SavedStateHandle#get(key)
andSavedStateHandle#set(key, value)
. The value is initialized by value of same key inintent.extra
orarguments
. - You can use a LiveData instance by
SavedStateHandle#getLiveData(key)
. If you change the LiveData instance’s value, a value of SavedStateHandle is changed.
# Problems in ViewModel-SavedState
- If you get a value by
SavedStateHandle#get(key)
, you don't only change the value but also need to callSavedStateHandle#set(key, value)
. SavedStateHandle
requires a key to use. The key needs to be same as a key ofintent.extra
orarguments
.SavedStateHandle
has restrictions on available types.
# Solutions by ViewModel-SavedState-ktx
- When you change the value,
SavedStateHandle#set(key, value)
is automatically called by Delegated Properties. - ViewModel-SavedState-ktx don’t requires a key to use
SavedStateHandle
. Instead, it uses property name. It provides extension methods for specifying property name inIntent
andBundle
. - You can use any type using
SavedStateAdapter
that converts between the type used inSavedStateHandle
and the type actually used inViewModel
.
# How to use ViewModel-SavedState-ktx
Pass parameters to the Intent
or Bundle
with an extension function using a property reference.
class SampleActivity : AppCompatActivity(R.layout.sample_activity) {
private val viewModel: SampleViewModel by viewModels() companion object {
@JvmStatic
fun createIntent(context: Context): Intent {
return Intent(context, SampleActivity::class.java).also {
it.putExtra(SampleViewModel::text, "sample")
}
}
}
}
You can use the extension function of SavedStateHandle in Delegated Property to get values and LiveData. Arbitrary type conversion can be performed with initial value setting and SavedStateAdapter.
class SampleViewModel(
savedStateHandle: SavedStateHandle
) : ViewModel() {
val text: String by savedStateHandle.property()
val count: MutableLiveData<Int> by savedStateHandle.liveData(initialValue = 0)
val timeUnit: MutableLiveData<TimeUnit?> by savedStateHandle.liveData(object : SavedStateAdapter<TimeUnit?, Int?> {
override fun toSavedState(value: TimeUnit?): Int = value?.ordinal
override fun fromSavedState(state: Int?): TimeUnit? = state?.let { TimeUnit.values()[it] }
})
}