import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
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(viewModel: CounterViewModel = viewModel()) {
val count by viewModel.counter.collectAsState()
Scaffold(
topBar = { TopAppBar(title = { Text("Counter Screen") }) },
content = { paddingValues ->
Column(
modifier = androidx.compose.ui.Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally
) {
Text(text = "Counter: $count", style = MaterialTheme.typography.headlineMedium)
Spacer(modifier = androidx.compose.ui.Modifier.height(24.dp))
Button(onClick = { viewModel.increment() }) {
Text("Increment")
}
}
}
)
}We use MutableStateFlow inside the CounterViewModel to hold the current count. This is private to prevent external modification. We expose a read-only StateFlow so the UI can observe changes.
The increment() function updates the counter value by increasing it by 1.
In the CounterScreen composable, we collect the StateFlow as Compose state using collectAsState(). This makes the UI automatically update when the counter changes.
The UI shows the current count in a Text and has a button labeled "Increment" that calls increment() when clicked.