@Composable fun CountUp() { var count: Int by remember { mutableStateOf(0) } Column { Text(text = "$count") Button( onClick = { count += 1 } ) { Text(text = "Count Up!") } } }
変数の宣言でby rememberとすることで状態の保存をし、状態の変化をトリガーとしてUIが更新される。
mutableStateOf(0)とすることで初期値が0になる
ただ、これだとView自身が状態を持つ変数countを持ってしまっている。
ViewModelを作ってそちら側に実際の状態を保持するように変更する。
ViewModel側
/** * カウントの状態を持つViewModel */ class CountViewModel : ViewModel() { /** * カウントの回数を保持する */ val count: MutableState<Int> = mutableStateOf<Int>(0) /** * カウントアップボタンのクリックイベントを処理する * [count]の値を1増やし、表示を更新する */ fun onCountUpTapped() { val currentValue = requireNotNull(count.value) count.value = currentValue + 1 } }
元々処理をしていたComposable側。
@Composable fun CountUp(viewModel: CountViewModel) { val count: Int by viewModel.count Column { Text(text = "$count") Button( onClick = { viewModel.onCountUpTapped() } ) { Text(text = "Count Up!") } } }
引数のviewModelはMainActivityのプロパティとして定義する
class MainActivity : ComponentActivity() { private val viewModel: CountViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CountUp(viewModel = viewModel) } } }