
Facilitates in-memory object retention with ViewModel, avoiding Parcelable. Supports ViewModel state restoration upon screen rotation and offers scoped ViewModel management and cleanup.
Remember any type of object with ViewModel. No Parcelable, just in-memory. (Why not?)
implementation("io.github.shirozatou:rem:1.2.0")
remember {
Any() // β Evaluated again when screen rotated
}
rememberSaveable {
Any() // β IllegalArgumentException. Cannot be stored to Bundle (Android)
}
rememberWithViewModel {
Any() // π₯³ Restore from ViewModel when screen rotated
}Remembered value is forget when
Currently only instance of Clearable is allowed.
var flag by remember { mutableStateOf(true) }
if (flag) {
val foo = rememberWithViewModel(key) {
object : Clearable {
val data = Any()
override fun onCleared() {
// Called on main thread once flag == false
}
}
}.data
}ViewModel should be managed by ViewModelStoreOwner
For scoped ViewModel, use ScopedViewModelStore:
ScopedViewModelStore {
val v1 = viewModel<YourViewModel>()
val v2 = viewModel<YourViewModel>()
ScopedViewModelStore {
val v3 = viewModel<YourViewModel>()
assert(v1 === v2)
assert(v1 !== v3)
}
}ScopedViewModelStore is a simple trick btw.
@Composable
fun ScopedViewModelStore(content: @Composable () -> Unit) {
val viewModelStoreOwner = rememberWithViewModel {
object : ViewModelStoreOwner, Clearable {
override val viewModelStore: ViewModelStore = ViewModelStore()
override fun onCleared() {
viewModelStore.clear()
}
}
}
CompositionLocalProvider(
LocalViewModelStoreOwner provides viewModelStoreOwner,
content = content
)
}ScopedSaveableStateRegistry {
LazyColumn {
items(count = 100) {
val remembered = rememberSaveable {
Any() // You can remember any type of object here
}
val notRemembered = rememberWithViewModel {
Any()
}
Text(text = remembered.toString())
Text(text = notRemembered.toString())
}
}
}Similar to ViewModel, don't leak Context or something.
Remember any type of object with ViewModel. No Parcelable, just in-memory. (Why not?)
implementation("io.github.shirozatou:rem:1.2.0")
remember {
Any() // β Evaluated again when screen rotated
}
rememberSaveable {
Any() // β IllegalArgumentException. Cannot be stored to Bundle (Android)
}
rememberWithViewModel {
Any() // π₯³ Restore from ViewModel when screen rotated
}Remembered value is forget when
Currently only instance of Clearable is allowed.
var flag by remember { mutableStateOf(true) }
if (flag) {
val foo = rememberWithViewModel(key) {
object : Clearable {
val data = Any()
override fun onCleared() {
// Called on main thread once flag == false
}
}
}.data
}ViewModel should be managed by ViewModelStoreOwner
For scoped ViewModel, use ScopedViewModelStore:
ScopedViewModelStore {
val v1 = viewModel<YourViewModel>()
val v2 = viewModel<YourViewModel>()
ScopedViewModelStore {
val v3 = viewModel<YourViewModel>()
assert(v1 === v2)
assert(v1 !== v3)
}
}ScopedViewModelStore is a simple trick btw.
@Composable
fun ScopedViewModelStore(content: @Composable () -> Unit) {
val viewModelStoreOwner = rememberWithViewModel {
object : ViewModelStoreOwner, Clearable {
override val viewModelStore: ViewModelStore = ViewModelStore()
override fun onCleared() {
viewModelStore.clear()
}
}
}
CompositionLocalProvider(
LocalViewModelStoreOwner provides viewModelStoreOwner,
content = content
)
}ScopedSaveableStateRegistry {
LazyColumn {
items(count = 100) {
val remembered = rememberSaveable {
Any() // You can remember any type of object here
}
val notRemembered = rememberWithViewModel {
Any()
}
Text(text = remembered.toString())
Text(text = notRemembered.toString())
}
}
}Similar to ViewModel, don't leak Context or something.