When the lazy column list item is long, the Keyboard covers the Textfield in Jetpack Compose

2.1k views Asked by At
  • I have a lazy list of text fields in jetpack compose (around 10 OutlineTextField())
  • The last few text fields are hidden by the keyboard
  • How can I move those lower text fields above the keyboard? Thank you
4

There are 4 answers

0
Fernando Cebollada Aucejo On

Add this on themes.xml in the style that your activity is using:

adjustResize|stateVisible

or android:windowSoftInputMode="adjustResize" in your manifest on activity that contain your list

0
Mr. Techie On

I have the following steps to get the desired output:

  1. In the manifest file add the following:
<manifest 
    ...
    ...>

    <application
        ...
        ...
        ...>

        <activity
            ...
            android:windowSoftInputMode="adjustResize"
            ...>
            ...
            ...
            ...
        </activity>
    </application>

</manifest>
  1. In your composable with LazyColumn get reference to the LazyListState and then observe the view tree like the following ScrollOnKeyboardVisibility() function.
@Composable
fun UI(){
    val lazyColumnState = rememberLazyListState()
    val coroutineScope = rememberCoroutineScope()
    Column {
        LazyColumn (
            state = lazyColumnState
        ){
            ...
            ...
            ...
        }
        ...
        ...
        ...    
    }
    ScrollOnKeyboardVisibility(lazyColumnState, coroutineScope)
}


@Composable
fun ScrollOnKeyboardVisibility(lazyListState: LazyListState, coroutineScope: CoroutineScope) {
    val currentView = LocalView.current
    val prevScrollPosition = currentView.bottom
    var keyboardSize by remember{ mutableStateOf(0)}

    currentView.viewTreeObserver.addOnGlobalLayoutListener {
        if (lazyListState.layoutInfo.visibleItemsInfo.isNotEmpty()) {
            val currentScreenSize = currentView.bottom
            if (currentScreenSize != actualScreenSize) { // keyboard is visible
                coroutineScope.launch {
                    delay(200)
                    if (keyboardHeight == 0){
                        keyboardHeight = actualScreenSize - currentScreenSize
                    }
                    lazyListState.animateScrollBy(keyboardHeight.toFloat())
                }
            }else {
                // keyboard is not visible
            }
        }
    }
}

Here, whenever keyboard becomes visible we scroll LazyColumn up by keyboard height and whenever keyboard becomes invisible scroll LazyColumn down by keyboard height

0
Dehan Wjiesekara On

You need to implement the accompanist-insets dependencies

implementation "com.google.accompanist:accompanist-insets:<version>"
// If using insets-ui
implementation "com.google.accompanist:accompanist-insets-ui:<version>"

Then use the ProvideWindowInsets(windowInsetsAnimationsEnabled = true) as showin in following code in your MainActivity.

setContent {
        ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
            MyApplicationTestTheme {
               //your content goes here
            }
        }
 }

For more details check out the documentation

0
David Aleksanyan On

In my case I had to remove the android:windowSoftInputMode="adjustResize" from the manifest and keyboard stopped jumping around after that.