【Android】コンストラクタに引数があるViewModelを使う
AndroidでViewModelを使用するとき、以下のようなコンストラクタに独自の引数があるViewModelを使用したいときがあります。今回は、その方法を解説します。
class MainViewModel(id: Int) : ViewModel()
独自Factoryの定義
ViewModelインスタンスの生成はViewModelのコンストラクタを直接呼び出すのではなくて、以下のようにFactoryクラスのcreateメソッドを呼び出して生成します。
if (mFactory instanceof KeyedFactory) { viewModel = ((KeyedFactory) mFactory).create(key, modelClass); } else { viewModel = mFactory.create(modelClass); }
よって、まずはコンストラクタに引数があるViewModelに対応したFactoryクラスを定義します。
class MainViewModel(id: Int) : ViewModel() { class Factory( private val id: Int ) : ViewModelProvider.NewInstanceFactory() { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { return MainViewModel(id) as T } } }
独自Factoryの使用
独自に定義したFactoryクラスは、そのインスタンスをViewModelProviderに渡す必要があります。ViewModelProviderのコンストラクタの中に、Factoryインスタンスを引数に持つコンストラクタがオーバーロードされているので、以下のようにそのコンストラクタを使用します。
class MainActivity : AppCompatActivity(R.layout.main_activity) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val viewModel = ViewModelProvider( this, MainViewModel.Factory(0) ).get(MainViewModel::class.java) } }
以上のようにして、コンストラクタに引数があるViewModelを使用できます。