Scroll To Textfield In Column On Jetpack Compose
Published:
You can either use
BringIntoViewRequester
read about it here
Read the documentation hereOr, use
Modifier.onGloballyPositioned { coordinates -> //save the value }
create an object that stores your textfield state (position) say textFieldState
.
class TextFieldState {
...
fun onGloballyPositioned(coordinates: LayoutCoordinates) {
scrollPosition = coordinates.positionInWindow().y.toInt()
}
...
}
next, getKeyboardVisibility
@Composable
fun getKeyboardVisibility(): State<Boolean> {
val keyboardState = remember { mutableStateOf(false) }
val view = LocalView.current
DisposableEffect(view) {
val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
val rect = Rect()
view.getWindowVisibleDisplayFrame(rect)
val screenHeight = view.rootView.height
val keypadHeight = screenHeight - rect.bottom
keyboardState.value = keypadHeight > screenHeight * 0.15
}
view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
onDispose {
view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
}
}
return keyboardState
}
then, handle it, every textfield on your screen.
@ExperimentalComposeUiApi
@Composable
fun HandleBottomTextField(
isKeyboardVisible: Boolean,
scrollState: ScrollState,
vararg textFieldStateList: BaseTextFieldState,
bottomInset: Int,
isTheLastScrollToBottom: Boolean = true,
coroutineScope: CoroutineScope,
) {
textFieldStateList.forEachIndexed { _, textFieldState ->
if (textFieldState.isFocused.value && isKeyboardVisible) {
LaunchedEffect(
textFieldState.isFocused.value,
isKeyboardVisible
) {
coroutineScope.launch {
delay(CommonUtil.DEFAULT_DELAY_SCROLL_IN_MILLISECONDS)
if(textFieldState == textFieldStateList.last() ||
textFieldState == textFieldStateList[textFieldStateList.lastIndex-1]){
scrollState.animateScrollTo(scrollState.maxValue)
} else {
scrollState.animateScrollBy(getScrollByValue(textFieldState.scrollPosition > 450, textFieldState.scrollPosition))
}
}
}
}
}
}
you can adjust yourself regarding the value
fun getScrollByValue(isPositionBelowCurrentScrollState: Boolean,
textFieldScrollPosition: Int) : Float {
if(isPositionBelowCurrentScrollState){
val scrollByValue = textFieldScrollPosition - 450
return scrollByValue.toFloat()
} else {
val scrollByValue = 450 - textFieldScrollPosition
return -scrollByValue.toFloat()
}
}
there it goes