OutlinedTextField jetpack compose behind the Keyboard

Viewed 1318

I using Jetpack Compose to make the application UI, but it has some issues: when the next button is clicked on the keyboard it moves the focus to the next TextField(Amount), which is fine, but the problem is the TextField keeps behind the keyboard, that means the screen animation is not triggering:

How to move the screen to the new next input?

@Composable
fun KeyboardSample() {
    Scaffold(
        modifier = Modifier
            .fillMaxSize()
            .padding(start = 16.dp, end = 16.dp),

        ) {

        val name = rememberSaveable { mutableStateOf("") }
        val updateName = { _name: String ->
            name.value = _name
        }

        val amount = rememberSaveable { mutableStateOf("") }
        val updateAmount = { _amount: String ->
            amount.value = _amount
        }

        TextFieldsToExperiment(
            name = name.value,
            updateName = updateName,
            amount = amount.value,
            updateAmount = updateAmount
        )

    }
}

@Composable
fun TextFieldsToExperiment(
    name: String,
    updateName: (String) -> Unit,
    amount: String,
    updateAmount: (String) -> Unit
) {
    val focusManager = LocalFocusManager.current
    val focusRequester = FocusRequester()
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Spacer(modifier = Modifier.height(390.dp))
        OutlinedTextField(
            value = name,
            onValueChange = updateName,
            label = { Text("Name") },
            placeholder = { Text(text = "Name") },
            singleLine = true,
            keyboardOptions = KeyboardOptions.Default.copy(
                capitalization = KeyboardCapitalization.Sentences,
                autoCorrect = true,
                keyboardType = KeyboardType.Text,
                imeAction = ImeAction.Next
            ),
            keyboardActions = KeyboardActions(onNext = {
                focusManager.moveFocus(FocusDirection.Down)
            }),
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 6.dp, start = 0.dp, end = 0.dp, bottom = 6.dp),
        )
        Text(text = "Hello")
        Spacer(Modifier.height(8.dp))
        OutlinedTextField(
            value = amount,
            onValueChange = updateAmount,
            label = { Text("Amount") },
            placeholder = { Text(text = "Amount") },
            singleLine = true,
            keyboardOptions = KeyboardOptions.Default.copy(
                capitalization = KeyboardCapitalization.Sentences,
                autoCorrect = true,
                keyboardType = KeyboardType.Text,
                imeAction = ImeAction.Done
            ),
            keyboardActions = KeyboardActions(onDone = {
                focusManager.clearFocus()
            }),
            modifier = Modifier
                .fillMaxWidth()
                .focusRequester(focusRequester)
                .padding(top = 6.dp, start = 0.dp, end = 0.dp, bottom = 6.dp),
        )

    }
}

Also, I add some pictures to illustrate better the issue:

UI without keyboard:

Name Focused

Amount Focused

3 Answers

Put your KeyboardSample() content in a LazyColumn like this

@Composable
fun KeyboardSample() {
     Scaffold(
          modifier = Modifier
               .fillMaxSize()
               .padding(
                    start = 16.dp,
                    end = 16.dp
               ),

          ) {

          val name = rememberSaveable { mutableStateOf("") }
          val updateName = { _name: String ->
               name.value = _name
          }

          val amount = rememberSaveable { mutableStateOf("") }
          val updateAmount = { _amount: String ->
               amount.value = _amount
          }

        
          LazyColumn{
             item {
                  TextFieldsToExperiment(
                       name = name.value,
                       updateName = updateName,
                       amount = amount.value,
                       updateAmount = updateAmount
                  )
             }
          }

     }
}

And most importantly add this to your activity in the manifest

android:windowSoftInputMode="adjustResize"

Just add this
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
after onCreate

did you try android:windowSoftInputMode="adjustPan" it moves the window up so that your textfield became visible

Related