Skip to content

Commit

Permalink
Merge pull request #8 from etiennelenhart/delegate-patch
Browse files Browse the repository at this point in the history
Delegate patch
  • Loading branch information
Etienne Lenhart authored Dec 20, 2017
2 parents ae1c647 + f42bb7d commit ec4919d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ class ProvidedFactoryViewModel<out T : ViewModel>(private val viewModelClass: Cl
*
* May be used in a [FragmentActivity] like this:
* ```
* val viewModel by providedFactoryViewModel<SampleViewModel>(sampleFactory)
* val viewModel by providedViewModel<SampleViewModel>(sampleFactory)
* ```
*
* @param[T] Type of the provided view model.
* @param[factory] Block to lazily get the factory to instantiate the view model.
*/
inline fun <reified T : ViewModel> FragmentActivity.providedFactoryViewModel(noinline factory: () -> ViewModelProvider.Factory): ProvidedFactoryViewModel<T> {
inline fun <reified T : ViewModel> FragmentActivity.providedViewModel(noinline factory: () -> ViewModelProvider.Factory): ProvidedFactoryViewModel<T> {
return ProvidedFactoryViewModel(T::class.java, factory)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ class ProvidedFragmentFactoryViewModel<out T : ViewModel>(private val viewModelC
* @param[T] Type of the provided view model.
* @param[factory] Block to lazily get the factory to instantiate the view model.
*/
inline fun <reified T : ViewModel> Fragment.providedFactoryViewModel(noinline factory: () -> ViewModelProvider.Factory): ProvidedFragmentFactoryViewModel<T> {
inline fun <reified T : ViewModel> Fragment.providedViewModel(noinline factory: () -> ViewModelProvider.Factory): ProvidedFragmentFactoryViewModel<T> {
return ProvidedFragmentFactoryViewModel(T::class.java, factory)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.etiennelenhart.eiffel.viewmodel.delegate

import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.support.v4.app.Fragment
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

/**
* Property delegate to lazily provide a shared [ViewModel] instantiated by a [ViewModelProvider.Factory]
* from the [ViewModelProvider] of this [Fragment]s Activity.
*
* May be used in a [Fragment] like this:
* ```
* val viewModel by SharedFactoryViewModel(SampleViewModel::class.java, sampleFactory)
* ```
*
* @param[T] Type of the provided view model.
* @param[viewModelClass] Java class of the provided view model.
* @param[factory] Block to lazily get the factory to instantiate the view model.
*/
class SharedFactoryViewModel<out T : ViewModel>(private val viewModelClass: Class<T>,
private val factory: () -> ViewModelProvider.Factory) : ReadOnlyProperty<Fragment, T> {

private var value: T? = null

override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
if (value == null) value = ViewModelProviders.of(thisRef.activity!!).get(viewModelClass)
return value!!
}
}

/**
* Convenience inline function to use [SharedFactoryViewModel] delegate with type parameter instead of Java class.
*
* May be used in a [Fragment] like this:
* ```
* val viewModel by sharedViewModel<SampleViewModel>(sampleFactory)
* ```
*
* @param[T] Type of the provided view model.
* @param[factory] Block to lazily get the factory to instantiate the view model.
*/
inline fun <reified T : ViewModel> Fragment.sharedViewModel(noinline factory: () -> ViewModelProvider.Factory): SharedFactoryViewModel<T> {
return SharedFactoryViewModel(T::class.java, factory)
}

0 comments on commit ec4919d

Please sign in to comment.