Skip to content

Instantly share code, notes, and snippets.

@NikolaDespotoski
Created October 24, 2019 23:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NikolaDespotoski/a6d67302afc46cdf2b423d1907849b4f to your computer and use it in GitHub Desktop.
Save NikolaDespotoski/a6d67302afc46cdf2b423d1907849b4f to your computer and use it in GitHub Desktop.
ViewModel Kotlin Property
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.javaType
class FragmentViewModelProperty<VM : ViewModel>(private val viewModelFactoryProvider: () -> ViewModelProvider.Factory? = { null },
private val shared: Boolean)
: ReadOnlyProperty<Fragment, VM> {
private lateinit var cachedViewModelProvider: ViewModelProvider
override fun getValue(thisRef: Fragment, property: KProperty<*>): VM = with(thisRef) {
val type = property.returnType.javaType as Class<VM>
if (!::cachedViewModelProvider.isInitialized) {
val store = if (!shared) viewModelStore else
requireActivity().viewModelStore
val factory = viewModelFactoryProvider()
?: if (!shared) thisRef.defaultViewModelProviderFactory else
requireActivity().defaultViewModelProviderFactory
cachedViewModelProvider = ViewModelProvider(store, factory)
}
cachedViewModelProvider.get(type)
}
}
class ActivityViewModelProperty<VM : ViewModel>(private val viewModelFactoryProvider: () -> ViewModelProvider.Factory? = { null })
: ReadOnlyProperty<AppCompatActivity, VM> {
private lateinit var cachedViewModelProvider: ViewModelProvider
override fun getValue(thisRef: AppCompatActivity, property: KProperty<*>): VM {
val type = property.returnType.javaType as Class<VM>
if (!::cachedViewModelProvider.isInitialized) {
val factory = viewModelFactoryProvider() ?: thisRef.defaultViewModelProviderFactory
cachedViewModelProvider = ViewModelProvider(thisRef, factory)
}
return cachedViewModelProvider.get(type)
}
}
inline fun <reified VM : ViewModel> Fragment.delegateViewModel(
noinline provider: () -> ViewModelProvider.Factory? = { null },
shared: Boolean = false) = FragmentViewModelProperty<VM>(viewModelFactoryProvider = provider, shared = shared)
inline fun <reified VM : ViewModel> AppCompatActivity.delegateViewModel(
noinline provider: () -> ViewModelProvider.Factory? = { null }) = ActivityViewModelProperty<VM>(viewModelFactoryProvider = provider)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment