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
MainActivity
class extendsComponentActivity
and defines the application's entry point. - In
onCreate
,setContent
composes the UI hierarchy using a custom theme (ComposeStateTheme
). - The
Scaffold
composes the overall layout with a top bar, content area, and background color.
2. Main Content with ViewModel (MainContent.kt):
- The
MainContent
composable defines the central content of the screen. - It uses
viewModel
to access an instance ofMyViewModel
. counter
observes the_counter
state flow from the ViewModel and stores the current value in a composable state.- A
Column
arranges the UI elements:- A
Text
displays the current counter value from the ViewModel. - A
Button
triggers theincrementCounter
function in the ViewModel.
- A
3. ViewModel for Counter State (MyViewModel.kt):
MyViewModel
extendsViewModel
and manages the application state.- It uses
MutableStateFlow
to hold the counter value (_counter
). counter
exposes the state flow as a read-onlyStateFlow
for composables to observe.incrementCounter
increases the internal counter value by 1.
4. Gradle Dependencies:
- The
build.gradle
file 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
- jetpack compose - IconButton from vector resource