[SOLVED] How can I get TextField value from another composable function in Jetpack Compose


This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under
CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

Issue

I have created one function called TextInput that contained TextField

@Composable
fun TextInput(
    inputType: InputType
) {
    var value by remember { mutableStateOf("") }

    TextField(
        modifier = Modifier.clip(RoundedCornerShape(30.dp)),
        value = value,
        onValueChange = { value = it },
        leadingIcon = { Icon(imageVector = inputType.icon, null) },
        label = { Text(text = inputType.label) },
        colors = TextFieldDefaults.textFieldColors(
            focusedIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent
        ),
        singleLine = true,
        keyboardOptions = inputType.keyboardOptions,
        visualTransformation = inputType.visualTransformation,
    )

}

Now on click of the button SIGN UPSIGN IN I want to access the value and show success/error based on validation.

        Button(
            onClick = {

                      //here

            },
            modifier = Modifier
                .padding(top = 30.dp)
                .width(200.dp),
            shape = RoundedCornerShape(20.dp)
        ) {
            Text(
                text = "SIGN IN",

                )
        }
==================================================
        Button(
            onClick = {

                    //here
            },
            modifier = Modifier
                .padding(top = 5.dp)
                .width(200.dp),
            shape = RoundedCornerShape(20.dp)
        ) {

            Text(text = "SIGN UP")
        }

If you want to see whole code to understand what i mean exactly.

@Composable
fun Sign_in_up_Screen() {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally
    ) {


        Image(
            painter = painterResource(R.drawable.login),
            contentDescription = "",
            modifier = Modifier
                .background(Color.Companion.Red)
                .fillMaxWidth()
        )

        TopTextButton()
    }
}

@Composable
fun Login_Screen() {
    val context = LocalContext.current
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(20.dp),
        modifier = Modifier.fillMaxSize()
    ) {

        TextInput(InputType.Email)
        TextInput(InputType.Password)

        Button(
            onClick = {

                      //here

            },
            modifier = Modifier
                .padding(top = 30.dp)
                .width(200.dp),
            shape = RoundedCornerShape(20.dp)
        ) {
            Text(
                text = "SIGN IN",

                )
        }

    }
}

@Composable
fun Signup_Screen() {
    val context = LocalContext.current
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(20.dp),
        modifier = Modifier.fillMaxSize()
    ) {

        TextInput(InputType.FullName)
        TextInput(InputType.Email)
        TextInput(InputType.Password)
        TextInput(InputType.ConfirmPassword)

        Button(
            onClick = {

                    //here
            },
            modifier = Modifier
                .padding(top = 5.dp)
                .width(200.dp),
            shape = RoundedCornerShape(20.dp)
        ) {

            Text(text = "SIGN UP")
        }

    }
}

sealed class InputType(
    val label: String,
    val icon: ImageVector,
    val keyboardOptions: KeyboardOptions,
    val visualTransformation: VisualTransformation
) {

    object FullName : InputType(
        label = "Full Name",
        icon = Icons.Default.Person,
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
        visualTransformation = VisualTransformation.None
    )

    object Email : InputType(
        label = "E-mail",
        icon = Icons.Default.Email,
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
        visualTransformation = VisualTransformation.None
    )

    object Password : InputType(
        label = "Password",
        icon = Icons.Default.Lock,
        keyboardOptions = KeyboardOptions(
            imeAction = ImeAction.Done,
            keyboardType = KeyboardType.Password
        ),
        visualTransformation = PasswordVisualTransformation()
    )

    object ConfirmPassword : InputType(
        label = "Confirm Password",
        icon = Icons.Default.Lock,
        keyboardOptions = KeyboardOptions(
            imeAction = ImeAction.Done,
            keyboardType = KeyboardType.Password
        ),
        visualTransformation = PasswordVisualTransformation()
    )

}

@Composable
fun TextInput(
    inputType: InputType
) {
    var value by remember { mutableStateOf("") }

    TextField(
        modifier = Modifier.clip(RoundedCornerShape(30.dp)),
        value = value,
        onValueChange = { value = it },
        leadingIcon = { Icon(imageVector = inputType.icon, null) },
        label = { Text(text = inputType.label) },
        colors = TextFieldDefaults.textFieldColors(
            focusedIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent
        ),
        singleLine = true,
        keyboardOptions = inputType.keyboardOptions,
        visualTransformation = inputType.visualTransformation,
    )

}

@Composable
fun TopTextButton() {

    var screen by remember { mutableStateOf(false) }

    Row(
        modifier = Modifier.padding(bottom = 40.dp),
    ) {

        TextButton( onClick = {
            if (screen)
                screen = !screen
        }) {
            Text(text = "Sign in")
        }

        Spacer(Modifier.width(145.dp))

        TextButton(onClick = {
            if (!screen)
                screen = !screen
        }) {
            Text(text = "Sign up")
        }
    }

    if (!screen){
        Login_Screen()
    }
    if (screen) {
        Signup_Screen()
    }
}

Is this code correct or should I put a function for each {Textfield}? So each text field has its own state

I am beginner android studio programming😅

Solution

You can add onValueChange param into TextInput like this;

@Composable
fun TextInput(
    inputType: InputType,
    onValueChange: (String) -> Unit
) {
   TextField(
      //
      onValueChange = {
         onValueChange(it)
         value = it
      }
      //
}

print your value;

TextInput(InputType.Email){ textFieldValue ->
   println(textFieldValue)
}

Answered By – commandiron

people found this article helpful. What about you?