0

I have the following code:

Column(
    modifier = modifier
        .padding(start = 30.dp, end = 30.dp, bottom = 30.dp)
        .verticalScroll(rememberScrollState()),
    verticalArrangement = Arrangement.spacedBy(10.dp),
    horizontalAlignment = Alignment.CenterHorizontally
) {
   ...
   val bringIntoViewRequester = remember { BringIntoViewRequester() }
    val coroutineScope = rememberCoroutineScope()
    OutlinedTextField(
        value = uiState.note,
        onValueChange = onNoteChange,
        label = { Text(text = stringResource(id = R.string.note)) },
        modifier = modifier
            .fillMaxWidth()
            .bringIntoViewRequester(bringIntoViewRequester)
            .onFocusEvent {
                if (it.isFocused) {
                    coroutineScope.launch {
                        // This sends a request to all parents that asks them to scroll so
                        // that this item is brought into view.
                        bringIntoViewRequester.bringIntoView()
                    }
                }
            }
    )

And then android:windowSoftInputMode="adjustResize"

If I enter a bunch of text into the text field, at some point I cannot see what I am typing anymore. My expectation is that the text field will scroll up such that what I am typing will still be visible. I am also calling WindowCompat.setDecorFitsSystemWindows(window, false) in MainActivity.

It is working with android:windowSoftInputMode="adjustPan", but then the top app bar gets pushed out of the window, which I don't want obviously.

DeKekem
  • 589
  • 10
  • 20

1 Answers1

1
@Composable
fun rememberImeState(): State<Boolean>{
val imeState = remember { mutableStateOf(false) }

    val view = LocalView.current
    
    DisposableEffect(key1 = view){
        val listener = ViewTreeObserver.OnGlobalLayoutListener {
            val isKeyboardOpen = ViewCompat.getRootWindowInsets(view)
                ?.isVisible(WindowInsetsCompat.Type.ime()) ?: true
            imeState.value = isKeyboardOpen
        }
        view.viewTreeObserver.removeOnGlobalLayoutListener(listener)
        onDispose {
            view.viewTreeObserver.removeOnGlobalLayoutListener(listener)
        }
    }
    return imeState

add this function in your app. and use it like this;

    val scrollState = rememberScrollState()
    val imeState = rememberImeState()

    LaunchedEffect(key1 = imeState.value) {
        if (imeState.value) {
            scrollState.scrollTo(Int.MAX_VALUE)
        }
    }

Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(scrollState)
    ) {
    //your stuff
}

LaunchEffect will be triggered every time imeState changes and it will take the maximum scroll state value that it can receive. This will ensure that the content remains constantly visible on the screen.

and add your manifest this line.

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

i hope its work.