1
votes

I have a huge RecyclerView with GridLayoutManager. Sometimes there's a small number of items shown, and I need to disable scroll in this case. Scroll should be enabled only when there're too many items to be shown in a RecyclerView, so scroll is needed.

Why? Because when a user clicks fast enough on items, the click listener is not triggered. User accidentally moves a RecyclerView a bit. Recycler's onTouchListener gets EVENT_MOVE and consumes the event.

I've tried to create custom GridLayoutManager with overridden canScrollVertically() method:

override fun canScrollVertically(): Boolean {
    return super.canScrollVertically() && isScrollEnabled
}

I use this function to check if the RecyclerView is scrollable:

fun RecyclerView.isScrollableVertically(): Boolean {
    return computeVerticalScrollRange() > height
}

Then, I update isScrollEnable field:

val isScrollableVertically = items_list.isScrollableVertically()
(category_items_list.layoutManager as CustomGridLayoutManager).setScrollEnabled(isScrollableVertically)

But even when there are a lot of items to show, items_list.isScrollableVertically() returns false.


I'm trying a lot of things to disable scroll when there's enough room for all items, but I haven't found a proper way to do this for a day. I will appreciate any help!

2

2 Answers

2
votes

The following code works for me in Kotlin:

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrollStateChanged( recyclerView: RecyclerView, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)
            // recyclerView.layoutManager!!.childCount) returns the number of visible items
            if (data.size <= recyclerView.layoutManager!!.childCount)
                recyclerView.stopScroll()
            }
})

This is called in the Activity/Fragment where you set the adapter for your recyclerView

EDIT: I've actually found that this condition works in more situations:

if (recyclerView.computeVerticalScrollRange() < recyclerView.height)

1
votes

Try to enable scrolling before you check if view is scrollable. Let see the implementation (java) of computeVerticalScrollRange method.

@Override
public int computeVerticalScrollRange() {
    if (mLayout == null) {
        return 0;
    }
    return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollRange(mState) : 0;
}

Once you have disabled scrolling you will always get zero scroll range in your case. So I think this should help

// set 'isScrollEnabled' true    
(category_items_list.layoutManager as CustomGridLayoutManager).setScrollEnabled(true)

val isScrollableVertically = items_list.isScrollableVertically()
(category_items_list.layoutManager as CustomGridLayoutManager).setScrollEnabled(isScrollableVertically)