Home > Mobile >  visibility of a part of screen when keyboard is open in jetpack compose
visibility of a part of screen when keyboard is open in jetpack compose

Time:01-29

I have code like this and I want the button on the bottom to be visible when keyboard is opened to edit the textfield.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp)
                    .verticalScroll(rememberScrollState())
                    .imePadding(),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(text = "LARGE TITLE", fontSize = 32.sp, fontWeight = FontWeight.Bold)
                Spacer(modifier = Modifier.height(400.dp))
                OutlinedTextField(value = "Sample Text", onValueChange = {})
                Spacer(modifier = Modifier.weight(1f))
                Button(onClick = { /*TODO*/ }) {
                    Text(text = "Sample Button")
                }
            }
        }
    }

I also have put android:windowSoftInputMode="adjustResize" in manifest. I achieved my purpose by adding reverseScrolling = true (.verticalScroll(rememberScrollState(), reverseScrolling = true)) to the column modifier with help of an answer of @Halifax to without reverseScrolling = true

with reverseScrolling = true

CodePudding user response:

First of all you need to ensure that the activity's windowSoftInputMode is set to adjustResize

<activity
      android:name=".MyActivity"
      android:windowSoftInputMode="adjustResize">
</activity>

Secondly setContent code will be like

setContent {
    Scaffold(
        contentWindowInsets = WindowInsets.safeDrawing,
        bottomBar = {
            Box(
                modifier = Modifier.fillMaxWidth(),
                contentAlignment = Alignment.Center
            ) {
                Button(onClick = { /*TODO*/ }) {
                    Text(text = "Sample Button")
                }
            }
        }
    ) { padding ->
        Column(
            modifier = Modifier
                .consumedWindowInsets(padding)
                .fillMaxSize()
                .padding(16.dp)
                .verticalScroll(rememberScrollState()),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "LARGE TITLE", fontSize = 32.sp, fontWeight = FontWeight.Bold)
            Spacer(modifier = Modifier.height(400.dp))
            OutlinedTextField(value = "Sample Text", onValueChange = {})
        }
    }
}

CodePudding user response:

Here is a slightly different solution that keeps the button in the column. It uses the BringIntoViewRequester to scroll the button into view whenever the size of the column is changed.

    setContent {
        val bringIntoViewRequester = remember { BringIntoViewRequester() }
        val coroutineScope = rememberCoroutineScope()
        val bringButtonIntoView: () -> Unit = {
            coroutineScope.launch {
                delay(1)
                bringIntoViewRequester.bringIntoView()
            }
        }
        Box(modifier = Modifier.imePadding()) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp)
                    .verticalScroll(rememberScrollState())
                    .onSizeChanged { bringButtonIntoView() },
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(text = "LARGE TITLE", fontSize = 32.sp, fontWeight = FontWeight.Bold)
                Spacer(modifier = Modifier.height(400.dp))
                OutlinedTextField(value = "Sample Text", onValueChange = {})
                Spacer(modifier = Modifier.weight(1f))
                Button(
                    onClick = { /*TODO*/ },
                    modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester),
                ) {
                    Text(text = "Sample Button")
                }
            }
        }
    }
  • Related