Skip to main content

Jetpack Compose with remember and mutableStateOf

 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 MainActivity
package 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.setValue
our var firstNum,secondNum are defined as mutableStateOf with default value " ". So when its value changes in 
onValueChange={firstNum=it}.
It will schedule recomposition and updates our UI.
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

Popular posts

Android List View using Custom Adapter and SQLite

following is a simple applicaton to create ListView using  Custom adapter.screenshot of the application  is like this . ListView is not used in android Anymore . We use  RecyclerView  and  CardView   in Android RecyclerView Demo is available on the following link http://androidtuts4u.blogspot.in/2017/04/android-recyclerview-example.html RecyclerView with Cardview Example is available on the following link http://androidtuts4u.blogspot.in/2017/09/android-card-view-example.html The ListView below the submit button is populated using Custom Adapter.Data is stored and retrieved using SQLite databsase. you can download the source code of this project from  google drive   https://drive.google.com/folderview?id=0BySLpWhqmbbdUXE5aTNhazludjQ&usp=sharing click on the above link ->sign into  your  google account ->add this to your google drive -> open it in google drive and download it. To create a simple ...

Swipe or OnFling Event Android

This  is a simple application Demonstrating Swipe or onFling() event on ListView. you can download the source code of this project from  google drive   https://drive.google.com/folderview?id=0BySLpWhqmbbdSVB4M0hXb0VxcU0&usp=sharing click on the above link ->sign into  your  google account ->add this to your google drive -> open it in google drive and download it. 1. Following is the MainActivity (DemoSwipe.java) of the application package com.arun.demolistviewswipe; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class DemoSwipe extends Activity { ListView lvCountry; Strin...

Android Card View And RecyclerView Example

CardView Cardview lets you show information inside cards that have consistent look across the platform . CardView is introduced with material design through support v7 library. CardView extends frame layout and It can have shadows and round corners.     Cards can be used as independent views that serves as an entry point to more detailed information. CardView can also  be used with RecyclerView to display cards as list. In this example we are using Cardview with Recyclerview to show data as list of cards. Our Demo application contains vertical list of cards . Each card contain Movie name, movie poster and director name. screenshot of demo app 1. CardView and RecyclerView are supportV7 library widget . so we need to add dependency for both in app level build.gradle file . which is in the app folder compile 'com.android.support:cardview-v7:26.+' compile 'com.android.support:recyclerview-v7:26.+' build.gradle file is apply plugin: 'com.android.applicat...