RecyclerView: отключить прокрутку, если места достаточно для всех элементов

У меня огромный RecyclerView с GridLayoutManager. Иногда отображается небольшое количество элементов, и в этом случае мне нужно отключить прокрутку. Прокрутку следует включать только тогда, когда в RecyclerView отображается слишком много элементов, поэтому прокрутка необходима.

Почему? Потому что, когда пользователь достаточно быстро нажимает на элементы, прослушиватель кликов не срабатывает. Пользователь случайно немного перемещает RecyclerView. Recycler onTouchListener получает EVENT_MOVE и использует событие.

Я попытался создать собственный GridLayoutManager с переопределенным методом canScrollVertically():

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

Я использую эту функцию, чтобы проверить, прокручивается ли RecyclerView:

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

Затем я обновляю поле isScrollEnable:

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

Но даже если элементов для отображения много, items_list.isScrollableVertically() возвращает false.


Я много чего пытаюсь отключить прокрутку, когда места достаточно для всех элементов, но за день не нашел подходящего способа сделать это. Буду признателен за любую помощь!


person Oleksandr Nos    schedule 28.01.2019    source источник


Ответы (2)


Попробуйте включить прокрутку, прежде чем проверять, можно ли прокручивать представление. Давайте посмотрим на реализацию (java) метода computeVerticalScrollRange.

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

После того, как вы отключили прокрутку, вы всегда будете получать нулевой диапазон прокрутки в вашем случае. Так что думаю должно помочь

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

val isScrollableVertically = items_list.isScrollableVertically()
(category_items_list.layoutManager as CustomGridLayoutManager).setScrollEnabled(isScrollableVertically)
person frumle    schedule 28.01.2019
comment
Большое тебе спасибо! Я хотел бы добавить, что я обновляю setScrollEnabled() после обновления набора данных для RecyclerView следующим образом: recycler_view.post { /* scroll check here*/ } - person Oleksandr Nos; 29.01.2019

У меня в Котлине работает следующий код:

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()
            }
})

Это вызывается в Activity/Fragment, где вы устанавливаете адаптер для вашего recyclerView.

РЕДАКТИРОВАТЬ: я действительно обнаружил, что это условие работает в большем количестве ситуаций:

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

person Ivan Narvaez    schedule 12.06.2019