State Management in Jetpack Compose

Sep 10 2024 · Kotlin 1.9.22, Android 34, Android Studio Iguana | 2023.2.1 Patch 2

Lesson 03: State Hoisting

Demo

Episode complete

Play next episode

Next
Transcript

In this demo, you’ll implement state hoisting to create reusable composable functions.

Start Android Studio and open the 03-lesson-state-hoisting/Starter project. Build and run the project. When you enter a new club member’s name, the name shows on the screen.

Open the SignUpScreen.kt file containing the starter code. The SignUpScreen() composable has a variable memberName whose value updates when a user enters a new club member’s name.

This works correctly. Now, you want to add another input field for the app user to enter the new club member’s email address. The components, one for the name and one for the email, are similar in look and behavior. In such a scenario, you can create a reusable stateless composable and reuse it.

In the SignUpScreen.kt file, you’ll create the FieldInputComponent() composable with the following parameters: label, inputValue and onInputValueChanged lambda:

@Composable
fun FieldInputComponent(
  modifier: Modifier = Modifier,
  label: String,
  inputValue: String,
  onInputValueChanged: (String) -> Unit
) {
  Column(modifier = modifier) {
    OutlinedTextField(value = inputValue,
      onValueChange = onInputValueChanged,
      shape = RoundedCornerShape(16.dp),
      modifier = Modifier.fillMaxWidth(),
      label = {
        Text(text = "Enter Member's $label")
      })
    Spacer(modifier = Modifier.height(32.dp))
    Text(text = "$label is $inputValue")
  }
}

The label identifies the input field, whether for the name or the email address. inputValue stores the value entered by the user. The onInputValueChanged lambda is called when the value entered by a user changes to update the value stored in the state variable.

The FieldInputComponent composable also contains the OutlinedTextField composable for users to enter a club member’s name and a Text composable to display the value entered.

Next, in the SignUpScreen() composable, replace the OutlinedTextField and Text composables with the FieldInputComponent composable and provide the required arguments:

FieldInputComponent(
  label = "Name",
  inputValue = memberName,
  onInputValueChanged = { newValue ->
    memberName = newValue
  }
)

Build and run the project.

The app works just like before. When you enter a new member’s name, it displays on the screen.

Now, you’ll add the email component. Luckily, you don’t have to create a new component from scratch. You can reuse the FieldInputComponent() composable you created earlier.

In the SignUpScreen() composable, create a new state variable memberEmail to hold the value of a member’s email:

var memberEmail  by remember { mutableStateOf("") }

Then, call the FieldInputComponent() composable with the email as the label and memberEmail as the inputValue:

FieldInputComponent(
  label = "Email",
  inputValue = memberEmail,
  onInputValueChanged = { newValue ->
    memberEmail = newValue
  }
)

Build and run the project.

Now, add some space between the name and email components to differentiate them:

Spacer(modifier = Modifier.height(40.dp))

Build and run the project. Just as before, when you enter a member’s name, it displays on the screen. When you enter a member’s email, the email also displays on the screen.

See forum comments
Cinema mode Download course materials from Github
Previous: Instruction 1 Next: Instruction 2