よくラボでViewModelって言葉聞くのですが、
なんの事やらさっぱりだったので個人的にまとめてみました。
ViewModelクラスとは?
役割を一言で言うと 「UIコンポーネントとデータ処理を切り分ける」 です。
アクティビティ(UIコンポーネント)にデータを保持させるのでは無く、
ViewModelクラスにデータを持たせる事で画面の再生成や様々な状態変化に対して
データの保持と同期を行います。
今回は、ViewModelを活用して
画面を回転をしても、保存した値が破棄されず
回転前に保存した値が表示されるような画面を作成します。
↑横画面にしても「123」と表示されるようにしたい。(右の方)
ViewModelの使い方
ViewModelを継承したクラスを作成
まず、ViewModelを継承したMyViewModelクラスを作成します。
中では、変数やメソッドを宣言します。
今回は、Int型の値を保持するための変数を宣言します。
class MyViewModel :ViewModel() {
var numHolder : Int = 0 //初期値
}
Activity内での設定
①ViewModelのインスタンスを取得
ActivityでViewModelを使用するには、インスタンスを取得する必要があります。
val myViewModel: MyViewModel
// 構成変更中もViewModelが生き残るようにViewModelProviderとAndroidViewModelFactoryを使用
myViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application))[MyViewModel::class.java]
②ViewModelの保持する値を更新
取得したインスタンスを使用し、保持している値を更新します。
今回は、EditTextViewに入力された値を保持するように設定します。
//保存ボタンを押された時
binding.saveButton.setOnClickListener {
//入力された値に更新
myViewModel.numHolder = binding.edit2.text.toString().toInt()
}
③更新した値を表示する
ボタンを押すとMyViewModelクラスの変数numHolderを表示する設定をします。
//表示ボタンを押された時
binding.displayButton.setOnClickListener {
//保持している値を表示
binding.viewModelSavedTextView.text = myViewModel.numHolder.toString()
}
実際に実行!
Activityに保存された場合とViewModelに保存された時を比較します。
どのような違いがあるのでしょうか?
Activityのコード
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
//この変数に格納された値が左の「ここに表示される」に表示される
private var activityNumHolder = 0
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//レイアウトのインフレート
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//ViewModelのインスタンスを取得
myViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application))[MyViewModel::class.java]
//保存ボタン
binding.saveButton.setOnClickListener {
activityNumHolder = binding.edit1.text.toString().toInt()
myViewModel.numHolder = binding.edit2.text.toString().toInt()
}
//表示ボタン
binding.displayButton.setOnClickListener {
binding.activitySavedTextView.text = activityNumHolder.toString()
binding.viewModelSavedTextView.text = myViewModel.numHolder.toString()
}
}
}
MyViewModelのコード
class MyViewModel :ViewModel() {
var numHolder : Int = 0 //初期値
}
①デフォルト画面
まずはデフォルト画面を確認しましょう。
「ここに表示される」にActivityとViewModelの変数の値が表示されます。
②変数の初期値の確認
表示ボタンを押して初期値を確認します。
今回はどちらも初期値は「0」に設定しました。
③入力した値を表示
以下の手順で入力した値を表示します。
値を入力→保存→表示
どちらも、値を保持し表示することができていますね!
④画面を横に回転
画面の構成をするとActivityは一度破棄されて、
再度OnCreate()から処理を行います。
値を表示するViewも一度初期化されるためどちらもデフォルト状態になっています。
⑤値の確認
表示ボタンを押して、保持して値の確認をします。
Activityで保持している値は、初期値になっており
ViewModelで保持している値は、更新した値になっていますね!
まとめ
ViewModelの超基本知識です!