QuarK
QuarK

Reputation: 1312

LayoutManager.startSmoothScroll scrolls to wrong position

I have a RecyclerView of goods with categories and HorizontalScrollView of good's categories above it. I am trying to implement the following behavior: when you click on category in scroll view, recycler scrolls to first good with this category.

To do it, I find first good with selected category in LiveData corresponding to recycler's content, then I find index of that good and begin to scroll recycler:

viewModel.stateLiveData.observe(viewLifecycleOwner) { state ->
    val category = state.category
    if (category.isNotEmpty()) {
        val smoothScroller = LinearSmoothScroller(context)
        val itemPositionWithCategory = viewmodel.getItemPositionWithCategory()
        smoothScroller.targetPosition = itemPositionWithCategory
        (binding.deliveryGoodsRecycler.layoutManager as LinearLayoutManager).startSmoothScroll(smoothScroller)
    }
}

Smooth scroll works strange. By default first category is checked and list is in 0 position. If I click on for instance seventh category, when first good with this category is found correctly and list is scrolled to that good normally.

Problems appear with scrolling "backward". If I check sixth category, when seventh one is selected, the scroll works fine and scrolls to first good with sixth category. But I check fifth category, when seventh one is selected, the recycler scrolls to zero position for some reason. This behavior appears every time, when recycler is scrolled "backward" with none zero gap between categories (scroll to previous category works correct).

I made debug for backward scroll, category is not changing during scroll, index of the first good with target category is correct and is not changing during scroll. I logged index in recycler's OnScrollListener, in function onScrolled. When recycler is scrolled to previous category, this function is called much less times, than recycler is scrolled to top. In both cases index is not changing while scroll.

I have no idea, why smooth scroll works wrong in particular cases. Hope someone, who knows recycler good or had similar problems, could help me.

Update

I am adding part of my layout to make situation clear.

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/main_delivery_appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="0dp">

    <HorizontalScrollView
        android:id="@+id/chips_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.chip.ChipGroup
            android:id="@+id/chip_categories"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:selectionRequired="true"
            app:singleLine="true"
            app:singleSelection="true" />
    </HorizontalScrollView>
</com.google.android.material.appbar.AppBarLayout>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/delivery_goods_recycler"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:overScrollMode="never"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Categories, which control position of recycler, are stored in chip_categories (there is no chips in layout, they are loaded from server and are added programmatically). chips_scroll_view allows to see all categories as they are not fit to screen width.

When I check category (chip) in chip_categories, selected category in state updates, this event is observed in fragment, then index of first good with selected category is found and delivery_goods_recycler is scrolled to that index. Bug appears when I check not previous category (one or more categories between them in left direction in chip_categories) and delivery_goods_recycler is scrolled to the top instead of found index.

Upvotes: 1

Views: 256

Answers (1)

shuk producation
shuk producation

Reputation: 1

As I understood you are scrolling a layout, you can scroll your Container(HorizontalScrollView) instead of using Layout Manager, HorizontalScrollView can contain your RecycleView inside the HorzintalScrollview.

Upvotes: 0

Related Questions