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 .

  • Forma de configurar las properties de PrimaryStage o Scene en TornadoFX
  • Kotlin-allopen para android
  • ¿Por qué var con private setter es una position invariante?
  • MapView en modo lite se bloquea cuando se llama onSaveInstanceState
  • No se puede usar fontawesomefx con kotlin y tornadofx
  • ClassNotFoundException en sabor personalizado usando kotlin
  • Configurando Kotlin en el nuevo Android Studio Project
  • Parsing xml kotlin android
  • Sala de Android select muchos a muchos LiveData
  • La vista personalizada no está dibujada en Android
  • Cómo componer nulables en Kotlin