Skip to content

Instantly share code, notes, and snippets.

View CostaFot's full-sized avatar
🍦

Costa Fotiadis CostaFot

🍦
View GitHub Profile
@CostaFot
CostaFot / RetainDecorator.kt
Created March 4, 2026 12:09
RetainDecorator.kt
class RetainDecorator<T : Any>(
retainedValuesStoreRegistry: RetainedValuesStoreRegistry,
) : NavEntryDecorator<T>(
decorate = { entry ->
logDebug { "Retaining ${entry.contentKey}" }
retainedValuesStoreRegistry.LocalRetainedValuesStoreProvider(entry.contentKey) {
entry.Content()
}
},
@Composable
fun GameScreen(
gameViewModel: GameViewModel = viewModel()
) {
// ...
}
@Composable
fun FirstScreen() {
val customRetainedViewModel = retain {
CustomRetainedViewModel()
}
val state by customRetainedViewModel.state.collectAsStateWithLifecycle()
// ....
}
@Composable
fun FirstScreen() {
val customRetainedViewModel = rememberRetainedViewModel<CustomRetainedViewModel>()
val state by customRetainedViewModel.state.collectAsStateWithLifecycle()
// .... rest of the owl
}
@Composable
inline fun <reified T : RetainedViewModel> rememberRetainedViewModel(noinline factory: (Context) -> T): T {
val context = LocalContext.current
return retain { factory(context) }
}
// ..compose layer
val customRetainedViewModel = rememberRetainedViewModel { context ->
EntryPoints.get(context, CustomRetainedViewModelEntryPoint::class.java).customRetainedViewModel()
}
@EntryPoint
@InstallIn(ActivityComponent::class)
interface CustomRetainedViewModelEntryPoint : RetainedViewModelEntryPoint<CustomRetainedViewModel>
@RetainedEntryPoint(CustomRetainedViewModelEntryPoint::class)
class CustomRetainedViewModel @Inject constructor(
// ...
) : RetainedViewModel() {
// ...
}
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class RetainedEntryPoint(
val value: KClass<out Any>,
)
interface RetainedViewModelEntryPoint<T : RetainedViewModel> {
fun create(): T
}
@EntryPoint
@InstallIn(ActivityComponent::class)
interface CustomRetainedViewModelEntryPoint : RetainedViewModelEntryPoint<CustomRetainedViewModel>
@EntryPoint
@InstallIn(ActivityComponent::class)
interface CustomRetainedViewModelEntryPoint {
fun customRetainedViewModel(): CustomRetainedViewModel
}
@Composable
fun rememberCustomRetainedViewModel(): CustomRetainedViewModel {
val context = LocalContext.current
return retain {
val entryPoint = EntryPoints.get(context, CustomRetainedViewModelEntryPoint::class.java)
interface RetainedViewModelEntryPoint<T : RetainedViewModel> {
fun create(): T
}