import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
class CounterViewModel : ViewModel() {
private val _counter = MutableStateFlow(0)
val counter: StateFlow<Int> = _counter.asStateFlow()
fun increment() {
_counter.value += 1
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: android.os.Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CounterScreen()
}
}
}
@Composable
fun CounterScreen(counterViewModel: CounterViewModel = viewModel()) {
val count by counterViewModel.counter.collectAsState()
Surface(modifier = androidx.compose.ui.Modifier.fillMaxSize()) {
Column(
horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally,
verticalArrangement = androidx.compose.foundation.layout.Arrangement.Center,
modifier = androidx.compose.ui.Modifier.fillMaxSize()
) {
Text(text = "Counter: $count", style = MaterialTheme.typography.headlineMedium)
Spacer(modifier = androidx.compose.ui.Modifier.height(16.dp))
Button(onClick = { counterViewModel.increment() }) {
Text("Increase")
}
}
}
}We use a MutableStateFlow in the CounterViewModel to hold the counter state. This allows the state to survive configuration changes like screen rotations because ViewModel lives longer than the Activity.
The counter is exposed as a read-only StateFlow. The increment() function updates the counter value.
In the CounterScreen composable, we collect the counter state as Compose state using collectAsState(). This makes the UI automatically update when the counter changes.
The UI shows the current counter value in a Text and a button labeled "Increase" that calls increment() in the ViewModel.