(KOTLIN) My solution uses a bit of reflection.
Suppose you do not want to create the same Factory class every time you create a new ViewModel class that needs arguments. You can do this with Reflection.
For example, you will have two different activities:
class Activity1 : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val args = Bundle().apply { putString("NAME_KEY", "Vilpe89") } val viewModel = ViewModelProviders.of(this, ViewModelWithArgumentsFactory(args)) .get(ViewModel1::class.java) } } class Activity2 : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val args = Bundle().apply { putInt("AGE_KEY", 29) } val viewModel = ViewModelProviders.of(this, ViewModelWithArgumentsFactory(args)) .get(ViewModel2::class.java) } }
And ViewModels for these activities:
class ViewModel1(private val args: Bundle) : ViewModel() class ViewModel2(private val args: Bundle) : ViewModel()
Then the magic part, implementing the Factory class:
class ViewModelWithArgumentsFactory(private val args: Bundle) : NewInstanceFactory() { override fun <T : ViewModel?> create(modelClass: Class<T>): T { try { val constructor: Constructor<T> = modelClass.getDeclaredConstructor(Bundle::class.java) return constructor.newInstance(args) } catch (e: Exception) { Timber.e(e, "Could not create new instance of class %s", modelClass.canonicalName) throw e } } }
source share