Mover la definición de ViewModel al método de nivel de package

Me gustaría mudarme:

ViewModelProviders.of(this).get(FooViewModel::class.java) 

en un método de nivel de package. Algo como esto:

 fun <T1, T2> T1.getViewModel(target: T1, targetViewModelClass: T2): Lazy<T2> { return ViewModelProviders.of(target).get(targetViewModelClass::class.java) } 

Sin embargo, esto me da 2 errores:

enter image description here

y

enter image description here


Pregunta: ¿hay alguna manera de completar esto?

Su parámetro T1 debe ser de tipo Fragment o FragmentActivity . Actualmente no es ninguno.
Además, para llamar a ::class.java , el tipo no debe ::class.java . Actualmente es T2: Any? . Además, T2 debe extender ViewModel .
Finalmente, para una API fácil, puede usar un tipo reificado .

Es posible que desee escribir:

 inline fun <reified T: ViewModel> Fragment.getViewModel(): Lazy<T> { return lazy { ViewModelProviders.of(this).get(T::class.java) } } 

Ahora puede usar esto como:

 class MyFragment : Fragment { fun foo() { val viewModelLazy = getViewModel<MyViewModel>() } } 

Puedes hacer lo mismo con FragmentActivity .

Esto debería funcionar:

 fun <T1: Fragment, T2: Any> T1.getViewModel(targetViewModelClass: KClass<T2>): Lazy<T2> { return ViewModelProviders.of(this).get(targetViewModelClass.java) } 

Uso:

 class FragmentA : Fragment() { fun foo() { getViewModel(SomeViewModel::class) } } 

El primer problema era que T1 podía ser de cualquier tipo en su function, pero el método de toma solo un Fragment o FragmentActivity . Usando T1: Fragment limita T1 a ser un Fragment (también puedes hacer esta FragmentActivity , por supuesto).

El segundo problema parece ser que targetViewModelClass puede ser nulo, puede targetViewModelClass esto restringiendo T2 para que sea un subtipo de Any , que es la class base de todos los types no obligatorios en Kotlin. Esto garantizará que null no se pueda pasar como ese parámetro.

Finalmente, según el consejo de @Kirill Rakhman, he ajustado el segundo parámetro para que se pueda llamar a la function con una instancia de KClass .

Aquí están los documentos oficiales sobre restricciones genéricas y parameters de types reificados .

  • ¿Por qué el comstackdor no encuentra la constante android.R.id.home?
  • Hibernate @OneToMany join table arroja StackOverflowException
  • IntelliJ importa Java Boolean y luego arroja un error
  • Kotlin: elementos condicionales durante la creación del map
  • Kotlin mutableMap foreach
  • Generar diagtwig de class de Kotlin
  • ¿Cómo get una class de time de ejecución de una variable en Kotlin?
  • Maven-publish gradle plugin se salta la versión
  • Referencia no resuelta a la function en Kotlin Android
  • La ambigüedad de resolución de sobrecarga en el número de parameters lambda
  • ¿Kotlin proporciona mejoras en el performance?