This code demonstrates how to manage UI state using ViewModel in a Jetpack Compose application. Here's a breakdown of the code:
1. Setting Up the Activity (MainActivity.kt):
- The
MainActivityclass extendsComponentActivityand defines the application's entry point. - In
onCreate,setContentcomposes the UI hierarchy using a custom theme (ComposeStateTheme). - The
Scaffoldcomposes the overall layout with a top bar, content area, and background color.
2. Main Content with ViewModel (MainContent.kt):
- The
MainContentcomposable defines the central content of the screen. - It uses
viewModelto access an instance ofMyViewModel. counterobserves the_counterstate flow from the ViewModel and stores the current value in a composable state.- A
Columnarranges the UI elements:- A
Textdisplays the current counter value from the ViewModel. - A
Buttontriggers theincrementCounterfunction in the ViewModel.
- A
3. ViewModel for Counter State (MyViewModel.kt):
MyViewModelextendsViewModeland manages the application state.- It uses
MutableStateFlowto hold the counter value (_counter). counterexposes the state flow as a read-onlyStateFlowfor composables to observe.incrementCounterincreases the internal counter value by 1.
4. Gradle Dependencies:
- The
build.gradlefile includes necessary dependencies:lifecycle-viewmodel-ktx: Provides core ViewModel functionality.lifecycle-viewmodel-compose: Integrates ViewModel with Jetpack Compose.
Summary
This example showcases how to separate UI state management from the composable UI using ViewModel. The ViewModel holds the counter value (_counter) and exposes it as a state flow (counter). The MainContent composable observes this state flow to display the counter and trigger updates by calling incrementCounter on the ViewModel. This separation keeps the UI logic clean and enables the ViewModel to survive configuration changes, ensuring state persistence.
MainActivity.kt
package com.cfsuman.composestate
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.cfsuman.composestate.ui.theme.ComposeStateTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeStateTheme {
Scaffold(
topBar = { TopAppBar(
title = {
Text(text = "Compose - ViewModel State")
}
)},
content = { MainContent() },
backgroundColor = Color(0xFFEDEAE0)
)
}
}
}
}
@Composable
fun MainContent() {
val viewModel = viewModel<MyViewModel>()
val counter = viewModel.counter.collectAsState()
Column(
Modifier.fillMaxSize().padding(24.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "${counter.value}", fontSize = 40.sp)
Button(onClick = { viewModel.incrementCounter() }) {
Text(text = "Increment Counter")
}
}
}
MyViewModel.kt
package com.cfsuman.composestate
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.*
class MyViewModel:ViewModel() {
private val _counter = MutableStateFlow(0)
val counter = _counter.asStateFlow()
fun incrementCounter(){
_counter.value +=1
}
}
build.gradle [app]
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-alpha06"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha06"
}
- jetpack compose - How to flow a list
- jetpack compose - flowOf flow builder
- jetpack compose - Convert list to flow
- jetpack compose - Count down flow
- jetpack compose - Flow using ViewModel
- jetpack compose - Count up flow by ViewModel
- jetpack compose flow - Room add remove update
- jetpack compose flow - Room implement search
- jetpack compose - Search Room data using ViewModel
- jetpack compose - ViewModel Room add insert data
- jetpack compose - ViewModel Room edit update data
- jetpack compose - ViewModel Room delete clear data
- compose glance - How to create app widget
- jetpack compose - Icon from vector resource