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 .

  • Usar las extensiones de resources de Kotlin para Android usando solo Maven
  • ¿Cómo se especifican los generics de tipado de pato (interfaz implícita) en Kotlin?
  • Problema con Kotlin después de que Android Studio se actualizó a 0.6
  • ¿Por qué kotlin no permite que el map mutable covariante sea un delegado?
  • Parámetros de layout relativo en kotlin
  • Crear una class de vista / grupo de visualización personalizada en Anko DSL
  • ¿Cómo sobrescribir el método al crear instancias de objects en Kotlin?
  • ¿Cómo corregir la ambigüedad de resolución de sobrecarga en Kotlin (sin lambda)?
  • La vista personalizada no está dibujada en Android
  • Cómo controlar cuándo las importaciones son reemplazadas por comodines en Android Studio en files de Kotlin
  • (número + "Es más de 5") No se está ejecutando "Error de concatenación"