Skip to content

Instantly share code, notes, and snippets.

@kakai248
Created April 17, 2020 17:07
Show Gist options
  • Save kakai248/065fbd986038fc475e59b1ad1e0b91ed to your computer and use it in GitHub Desktop.
Save kakai248/065fbd986038fc475e59b1ad1e0b91ed to your computer and use it in GitHub Desktop.
@MainThread
inline fun <reified VM : ViewModel> ComponentActivity.viewModel(
noinline provider: (SavedStateHandle) -> VM
) = createLazyViewModel(
viewModelClass = VM::class,
savedStateRegistryOwnerProducer = { this },
viewModelStoreOwnerProducer = { this },
viewModelProvider = provider
)
@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModel(
noinline provider: (SavedStateHandle) -> VM
) = createLazyViewModel(
viewModelClass = VM::class,
savedStateRegistryOwnerProducer = { this },
viewModelStoreOwnerProducer = { this },
viewModelProvider = provider
)
@MainThread
inline fun <reified VM : ViewModel> Fragment.parentViewModel() = createLazyViewModel(
viewModelClass = VM::class,
savedStateRegistryOwnerProducer = { requireParentFragment() },
viewModelStoreOwnerProducer = { requireParentFragment() },
viewModelProvider = {
throw IllegalStateException("${VM::class.java.name} should already exist scoped to the parent fragment.")
}
)
@MainThread
inline fun <reified VM : ViewModel> Fragment.activityViewModel() = createLazyViewModel(
viewModelClass = VM::class,
savedStateRegistryOwnerProducer = { requireActivity() },
viewModelStoreOwnerProducer = { requireActivity() },
viewModelProvider = {
throw IllegalStateException("${VM::class.java.name} should already exist scoped to the activity.")
}
)
fun <VM : ViewModel> createLazyViewModel(
viewModelClass: KClass<VM>,
savedStateRegistryOwnerProducer: () -> SavedStateRegistryOwner,
viewModelStoreOwnerProducer: () -> ViewModelStoreOwner,
viewModelProvider: (SavedStateHandle) -> VM
) = ViewModelLazy(viewModelClass, { viewModelStoreOwnerProducer().viewModelStore }) {
object : AbstractSavedStateViewModelFactory(savedStateRegistryOwnerProducer(), Bundle()) {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
return viewModelProvider(handle) as T
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment