AnteGemini
AnteGemini

Reputation: 586

TextField is hiding under the keyboard when focused

I have a problem with TextField that is hiding under the keyboard, I've found the answers for the similar question here, but they are not helping me in my case. I have a LazyColumn with the list of different composables in it, and when I have not enough elements in the window for scroll to be activated, focusing on TextField is not lifting up focused TextField above keyboard. Keyboard just hides it. My code:

val listState = rememberLazyListState()
typealias ComposableType = @Composable (Int) -> Unit
val uiList = listOf<ComposableType>( {IconButton}, {Text}, {CustomTextField(listState,it)}, {CustomTextField(listState,it)})
LazyColumn() {
    itemsIndexed(uiList) { index, ui ->
                ui.invoke(index)
        }
}

val scope = rememberCoroutineScope()
@Composable
CustomTextField(scrollState: LazyListState, position: Int) {
    OutlinedTextField(
        modifier = Modifier.onFocusEvent { focusState ->
            if (focusState.isFocused) {
                scope.launch {
                    scrollState.animateScrollToItem(position)
                }
            }
    )    
}

So, for example if i have 10 CustomTextFields in my uiList, scroll works when one of TextField is focused. But when there are only 2 TextFields in the uiList, focusing on either of them does not lift up them above keyboard.

Also I tried using RelocationRequester() and used Column with scroll instead of LazyColumn, none of it helped.

Upvotes: 15

Views: 10140

Answers (4)

Muhammad Ammar
Muhammad Ammar

Reputation: 556

You can resolve this by using consumeWindowInsets(contentPadding).imePadding() smooth and best!

Surface(onClick = {}) {
        Scaffold{ contentPadding->
        Column(
                Modifier
                    .fillMaxSize().
                    consumeWindowInsets(contentPadding).imePadding()
                    .focusable()
                    .background(MaterialTheme.colorScheme.background)
            ) 

Upvotes: 0

Aslm Monir
Aslm Monir

Reputation: 146

Add this to your activity in manifest file

 android:windowSoftInputMode="adjustResize"

And in the column for example use :

   Column (horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxWidth()
            .wrapContentHeight()
            .navigationBarsPadding().imePadding()
            .verticalScroll(rememberScrollState())
            .fillMaxHeight()
            .padding(top = 20.dp))

works for me , happy coding ..

Upvotes: 7

Sarojini2064130
Sarojini2064130

Reputation: 221

  1. You need to add this in your activity's declaration in AndroidManifest.xml

    android:windowSoftInputMode="adjustResize"

  2. You have to set wrapContentHeight().navigationBarsWithImePadding() to the modifier of parent composable

    Column(modifier = Modifier.wrapContentHeight().navigationBarsWithImePadding()){}

This solution worked for me.

Upvotes: 2

nglauber
nglauber

Reputation: 23994

It's a combination of things...

  1. You need to add this in your activity's declaration in Android.xml
android:windowSoftInputMode="adjustResize"
  1. Use BringIntoViewRequester as modifier in your TextField as you mentioned.
.bringIntoViewRequester(yourBringIntoViewRequester)
  1. The steps above worked for me when the component gain focus programatically (using FocusRequester). However, when the user taps on the TextField, it didn't work for me. So I implemented a workaround (which I'm not very proud of): when the TextField gain focus, I wait a bit to use the RelocationRequester. So I added this modifier to my TextField.
.onFocusEvent {
    if (it.isFocused) {
        coroutineScope.launch {
            delay(200)
            yourBringIntoViewRequester.bringIntoView()
        }
    }
}

These three things worked for me.

Upvotes: 20

Related Questions