I have UI like this:
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxSize(1F)
.padding(horizontal = 16.dp)
.verticalScroll(scrollState)
) {
TextField(...)
// multiple textfields
TextField(
//...
modifier = Modifier.focusOrder(countryFocus).onFocusChanged {
if(it == FocusState.Active) {
// scroll to this textfield
}
},
)
}
I have multiple TextFields in this column and when one of them is focused I want to scroll Column to it. There is a method in scrollState scrollState.smoothScrollTo(0f)
but I have no idea how to get a focused TextField position.
Update:
It seems that I've found a working solution. I've used onGloballyPositioned
and it works. But I'm not sure if it the best way of solving this.
var scrollToPosition = 0.0F
TextField(
modifier = Modifier
.focusOrder(countryFocus)
.onGloballyPositioned { coordinates ->
scrollToPosition = scrollState.value + coordinates.positionInRoot().y
}
.onFocusChanged {
if (it == FocusState.Active) {
scope.launch {
scrollState.smoothScrollTo(scrollToPosition)
}
}
}
)
It seems that using LazyColumn
and LazyListState.animateScrollToItem()
instead of Column
could be a good option for your case.
Reference: https://developer.android.com/jetpack/compose/lists#control-scroll-position
By the way, thank you for the information about onGloballyPositioned()
modifier. I was finding a solution for normal Column
case. It saved me a lot of time!
There is a new thing in compose called RelocationRequester
. That solved the problem for me. I have something like this inside of my custom TextField.
val focused = source.collectIsFocusedAsState()
val relocationRequester = remember { RelocationRequester() }
val ime = LocalWindowInsets.current.ime
if (ime.isVisible && focused.value) {
relocationRequester.bringIntoView()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With