Skip to content

Instantly share code, notes, and snippets.

@rahulsainani
Created November 11, 2021 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rahulsainani/000749c43dc7149fe85af73e42837fc2 to your computer and use it in GitHub Desktop.
Save rahulsainani/000749c43dc7149fe85af73e42837fc2 to your computer and use it in GitHub Desktop.
A workaround to make TextField scroll inside a scrolling parent so it doesn't go behind the ime. https://issuetracker.google.com/issues/192043120
@Composable
private fun ScrollingTextField(
text: String,
onValueChange: (String) -> Unit,
scrollState: ScrollState,
) {
val interactionSource = remember { MutableInteractionSource() }
val interactionSourceState = interactionSource.collectIsFocusedAsState()
val coroutineScope = rememberCoroutineScope()
val ime = LocalWindowInsets.current.ime
val textSize = remember { mutableStateOf(IntSize.Zero) }
val previousScrollState = remember { mutableStateOf(scrollState.value) }
TextField(
value = text,
onValueChange = onValueChange,
backgroundColor = Theme.colors.surface,
keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Sentences),
interactionSource = interactionSource,
modifier = Modifier
.onGloballyPositioned { textSize.value = it.size }
.fillMaxWidth()
)
LaunchedEffect(ime.isVisible, interactionSourceState.value) {
if (interactionSourceState.value) {
coroutineScope.launch {
if (ime.isVisible) {
previousScrollState.value = scrollState.value
delay(DELAY_BEFORE_SCROLL_ANIMATION_MS)
scrollState.animateScrollTo(ime.bottom + textSize.value.height)
} else {
delay(DELAY_BEFORE_SCROLL_ANIMATION_MS)
scrollState.animateScrollTo(previousScrollState.value)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment