https://github.com/shirozatou/rem
Remember any type of object with ViewModel. Scoped ViewModel Store.
https://github.com/shirozatou/rem
android-library compose-multiplatform compose-multiplatform-library viewmodel
Last synced: about 1 month ago
JSON representation
Remember any type of object with ViewModel. Scoped ViewModel Store.
- Host: GitHub
- URL: https://github.com/shirozatou/rem
- Owner: shirozatou
- Created: 2025-02-03T07:33:28.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-10-05T12:07:07.000Z (8 months ago)
- Last Synced: 2025-10-05T14:23:36.768Z (8 months ago)
- Topics: android-library, compose-multiplatform, compose-multiplatform-library, viewmodel
- Language: Kotlin
- Homepage:
- Size: 74.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# rem
Remember any type of object with ViewModel. No Parcelable, just in-memory. (Why not?)
## Dependency
`implementation("io.github.shirozatou:rem:1.2.0")`
## Usage
```kotlin
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
- once goes out of scope
- key changed
- viewModel in current scope is cleared
### Clean up
Currently only instance of `Clearable` is allowed.
```kotlin
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
}
```
### Can I remember ViewModel with rememberWithViewModel?
ViewModel should be managed by `ViewModelStoreOwner`
For scoped ViewModel, use `ScopedViewModelStore`:
```kotlin
ScopedViewModelStore {
val v1 = viewModel()
val v2 = viewModel()
ScopedViewModelStore {
val v3 = viewModel()
assert(v1 === v2)
assert(v1 !== v3)
}
}
```
ScopedViewModelStore is a simple trick btw.
```kotlin
@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
)
}
```
### Solution for LazyList
```kotlin
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())
}
}
}
```
### Reminder
Similar to `ViewModel`, don't leak `Context` or something.