Search code examples
androidandroid-jetpack-composeimesamsung

Enormous ime padding in Jetpack Compose


I have a pinned bottom container with a textfield. And i use imePadding modifier. When keyboard appears seems like imePadding works twice. It happens only on some devices. Particular my is Samsung Galaxy A80 (Android 11)

Code example

Scaffold(
    modifier = Modifier.fillMaxSize(),
    bottomBar = {
        Box(
            Modifier
                .imePadding()
                .height(100.dp)
                .background(Color.Red),
        ) {
            BasicTextField(
                modifier = Modifier.fillMaxWidth(),
                value = "some text",
                onValueChange = {},
            )
        }
    },
) {
    Box(
        Modifier.fillMaxSize().padding(bottom = it.calculateBottomPadding()),
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
        ) {
            repeat((0..100).count()) {
                item {
                    Box(Modifier.fillMaxWidth().height(100.dp).background(Color.Blue)) {
                    }
                }
            }
        }
    }
}

enter image description here enter image description here

UPD Issue reproduce when I add:

window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

Solution

  • I also had this issue; more specifically, some devices would seem to ignore adjustResize, but adding imePadding alongside adjustResize would cause others to double it up.

    I solved it for myself in the following way:

    1. Set the manifest option to android:windowSoftInputMode="adjustNothing"
    2. Set imePadding wherever needed.
    3. If setting imePadding on the contents of a scaffold, I also called, consumeWindowInsets(contentPadding) on the Modifier of those contents, before imePadding, otherwise the contentPadding got consumed additively in the imePadding.

    Something like:

    Scaffold(...){ contentPadding -> 
        Box(
            modifier = Modifier
                .padding(contentPadding)
                .consumeWindowInsets(contentPadding)
                .imePadding()
        ){...}
    }
    

    I can't guarantee that this is best practice or that it works in all cases, but it worked for me.