4

I have a RecyclerView that's hosting items rendered with Jetpack Compose. The height of the items varies. When scrolling from the top of the list to the bottom, scrolling is smooth. However, when scrolling back to the top, the items in the list jump when the height of the next item to appear at the top of the screen differs from the height of the item that was previously at the top of the screen.

The layout height of each ComposeView is set to WRAP_CONTENT. The previous XML layouts scrolled smoothly in both directions.

I am using Compose 1.2.0 and RecyclerView 1.3.0-beta01.

Is there a solution for having smooth scrolling in both directions?

Update: I have reported a bug here and provided a sample project demonstrating the problem here.

Neal Stublen
  • 815
  • 11
  • 14
  • Have you tried using a LazyColumn instead of a recycling view? – Augusto Alonso Jul 26 '22 at 00:31
  • @AugustoAlonso, using `LazyColumn` will resolve this problem and it is the long-term plan. We just have some item view types in this `RecyclerView` that we haven't yet migrated to Compose and I was hoping we could perform the migration one view type at a time without seeing significant issues. – Neal Stublen Jul 27 '22 at 01:32

2 Answers2

1

A little late but which version of Compose are you using?

I came across this in version 1.2.0-alpha06 release notes:

"Upgrading both RecyclerView and Compose will now result in much better scrolling performance for RecyclerViews with Compose views as children."

Maybe you need to update to the latest (1.2.0-alpha06 was released in March 2022)...

Code Poet
  • 6,222
  • 2
  • 29
  • 50
  • 1
    Thanks for the suggestion. I've updated the original question to indicate I'm using Compose 1.2.0 and RecyclerView 1.3.0-beta01. I've also added links to where I filed a bug report and a sample project. – Neal Stublen Aug 02 '22 at 17:58
0

try this. Suppose the item view is a ComposeView, do this in onBindViewHolder:

composeView.getChildAt(0)?.requestLayout()

This can fix the jumping. But it might have some performance impact. Make your own choice.

here is my item.xml.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<androidx.compose.ui.platform.ComposeView
    android:id="@+id/composeItem"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</layout>

and do this in Adapter's onBindViewHolder():

findView<ComposeView>(R.id.composeItem).apply {
 // avoid wrapContent jump
    getChildAt(0)?.requestLayout()
    setContent {
       // your own Composable method
        Content()
    }
}
xu xu
  • 1
  • 1