[Resolved] Do we have an out-of-the-box solution t...
# compose
n
[Resolved] Do we have an out-of-the-box solution to move the first visible item upwards when the IME appears 👀?
this is the behaviour i expected. LazyColumn can animate its position along with the input method editor (IME) regardless of the content being displayed
I think if we can obtain the height of ime, we can try to achieve this effect by using
animateScrollToItem(offset = height)
🤔
n
I don't think this is what I want because
imeNestedScroll
requires a gesture swipe to trigger. What I want is for LazyColumn to automatically animate with ime movement after clicking the textfield
s
What are you doing atm with the ime insets? You can pad the entire lazy column up based on the ime insets and see how that feels
n
to archive this https://kotlinlang.slack.com/archives/CJLTWPH7S/p1714447901418709?thread_ts=1714444753.429609&cid=CJLTWPH7S I have tried some methods from the documentation, but I still haven't achieved the same result as in the video.
https://developer.android.com/static/develop/ui/compose/images/layouts/insets/edge-to-edge-lazy-column-textfields.mp4 This is a video in the document. but seems to only work with Textfields in LazyColumn and not with other Composables like Text. Components other than TextField used in LazyColumn will be covered by the ime when ime is launched
For those who have similar concerns or are interested in this issue, here is solution
Copy code
val navigationBarHeight = WindowInsets.navigationBars.getBottom(density)
val imeOffset = WindowInsets.imeAnimationTarget.getBottom(density)
var imeHeight by remember { mutableIntStateOf(0) }

val visibleItemsIndex by remember {
  derivedStateOf {
    listState.layoutInfo.visibleItemsInfo.fastMap { it.index }
  }
}

val isContainLastIndex by remember {
  derivedStateOf {
    visibleItemsIndex.contains(listState.layoutInfo.totalItemsCount - 1)
  }
}

SideEffect {
  if (listState.layoutInfo.totalItemsCount > 0) {
    scope.launch {
      when (imeOffset) {
        0 -> {
          listState.animateScrollBy(
            value = if (isContainLastIndex) 0f else -imeHeight.toFloat() + navigationBarHeight.toFloat(),
            animationSpec = tween(250)
          )
        }
        else -> {
          imeHeight = imeOffset
          listState.animateScrollBy(
            value = imeOffset.toFloat() - navigationBarHeight.toFloat(),
            animationSpec = tween(250)
          )
        }
      }
    }
  }
}