Jetpack Compose is a modern declarative UI Toolkit . In jetpack's declarative approach widgets are stateless and does not expose getter or setter function . So we cannot update UI with button.setText(String) or img.setImageBitmap()....
In Compose we build UI by defining set of Composable function. Composable function take in data and emit UI elements. So in Compose only way to update the UI is by calling the same Composable function with new Arguments. This Argument represents UI State. State in an app is any value that changes over time , this includes simple class variable to Room Database. Any time a State is updated we need to call the Composable with new State to update the UI. This is called ReComposition.
This Demo Jetpack Compose app will help you understand the basics of Jetpack Compose.
Screenshots of this App
This is our MainActivitypackage com.arun.androidtutsforu.democompose 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.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.arun.androidtutsforu.democompose.ui.theme.DemoComposeTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DemoComposeTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { CalculateScreen() } } } } } @Composable fun CalculateScreen(){ var firstNum by remember { mutableStateOf("")} var secondNum by remember { mutableStateOf("")} val num1 = firstNum.toIntOrNull()?:0 val num2 = secondNum.toIntOrNull()?:0 val sum = num1+num2 Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "JetPack Compose Demo", fontWeight = FontWeight.Bold, fontSize = 20.sp, color = Color.Blue ) Spacer(modifier = Modifier.height(32.dp)) TextField( value =firstNum , onValueChange ={firstNum = it} , label = { Text(text = "Enter First Num")} ) Spacer(modifier = Modifier.height(16.dp)) TextField( value = secondNum, onValueChange = {secondNum=it}, label = { Text(text = "Enter Second Num")} ) Spacer(modifier = Modifier.height(16.dp)) Text( text = "The sum is $sum", fontWeight = FontWeight.Bold, fontSize = 20.sp ) } }
@Composable fun CalculateScreen(){ .... .... }This is our Composable function . In Compose we build UI by defining set of Composable function
Column(modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { .... .... }we use Column to place elements vertically on the screen
var firstNum by remember { mutableStateOf("")} var secondNum by remember { mutableStateOf("")}
mutableStateOf is an Observable type integrated with android runtime.So when we define any state as mutableStateOf , any changes to that state will schedule recomposition of every composable function that reads that state.
Composable uses remember API to store an object in memory . Stored value is returned during recomoposition. We use remember and mutableStateof to update the UI.
val value = remember{mutableStateof(default) val value by remember{muableStateof(default)
when we use by delegates we use the following imports
import androidx.compose.runtime.getValue import androidx.compose.runtime.setValueour var firstNum,secondNum are defined as mutableStateOf with default value " ". So when its value changes in
TextField( value =firstNum , onValueChange ={firstNum = it} , label = { Text(text = "Enter First Num")} ) ... TextField( value = secondNum, onValueChange = {secondNum=it}, label = { Text(text = "Enter Second Num")} )remember helps us retain the State across recomposition . But when configuration changes happens (rotation of the device ) and on process death whole activity restarts and all the state will be lost. So We must use rememberSeaveble instead of remember , rememberSeaveble will survive configuration changes and process death . rememberSaveable automatically saves any value that can be saved in a Bundle. For other values we can pass a custom saver objects
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { DemoComposeTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { CalculateScreen() } } } } } @Composable fun CalculateScreen(){ var firstNum by rememberSaveable{ mutableStateOf("")} var secondNum by rememberSaveable { mutableStateOf("")} val num1 = firstNum.toIntOrNull()?:0 val num2 = secondNum.toIntOrNull()?:0 val sum = num1+num2 Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "JetPack Compose Demo", fontWeight = FontWeight.Bold, fontSize = 20.sp, color = Color.Blue ) Spacer(modifier = Modifier.height(32.dp)) TextField( value =firstNum , onValueChange ={firstNum = it} , label = { Text(text = "Enter First Num")} ) Spacer(modifier = Modifier.height(16.dp)) TextField( value = secondNum, onValueChange = {secondNum=it}, label = { Text(text = "Enter Second Num")} ) Spacer(modifier = Modifier.height(16.dp)) Text( text = "The sum is $sum", fontWeight = FontWeight.Bold, fontSize = 20.sp ) } }You can Download full Source code of this App From my github
Comments
Post a Comment