Вложенные Recyclerview прокручиваются сами по себе

У меня есть родительский recyclerview, в котором есть 3 дочерних представления. Последние два ребенка являются recyclerview.

Parent recyclerview
 - child view 1
 - child view 2 (horizontal rv)
 - child view 3 (horizontal rv)

Проблема заключается в том, что каждый раз, когда этот фрагмент видимый, он прокручивается, чтобы выровнять его с child view 2 снизу.

Я установил родительский rv для прослушивания прокрутки. Вот что я получаю:

dy: 108
dy: 72
dy: 75
dy: 62
dy: 48
dy: 42
dy: 34
dy: 27
dy: 22
dy: 16
dy: 12
dy: 10
dy: 7
dy: 5
dy: 3
dy: 3
dy: 1
dy: 1
dy: 1

Кажется, что начальный dy родительского recyclerview установлен в 0 на child view 2 rv. Все, что находится выше, - это ценность. Тем не менее, я не уверен, было ли это так, поскольку я все еще выяснял, что вызывает его.

Любое исправление?

Ответ 1

У нас есть аналогичная проблема. У нас есть вертикаль RecyclerView. Каждый элемент этой вертикали RecyclerView содержит горизонтальный RecyclerView, как в приложении Android TV.

Когда мы обновили файлы поддержки с 23.4.0 до 24.0.0, неожиданно появился автоматический свиток. В частности, когда мы открываем Activity, а затем возвращаемся назад, вертикальный RecyclerView прокручивается так, что текущая горизонтальная строка RecyclerView не обрезается, и строка отображается полностью.

Есть легкое исправление. Добавьте это в свой внешний/родительский RecyclerView:

android:descendantFocusability="blocksDescendants"

Я нашел решение в следующих вопросах:

Кроме того, я нашел другое решение, которое также работает. В нашем случае вертикаль RecyclerView содержится внутри a FrameLayout. Если я добавлю android:focusableInTouchMode="true" к этому FrameLayout, проблема исчезнет.

Кстати, есть также открытая проблема в AOSP.

Ответ 2

А, я боролся за исправление. Решение на самом деле очень простое. В качестве ссылки для меня (и любого другого, кто сталкивается с той же проблемой в будущем), я просто должен setFocusable() в дочернем представлении rv до false, и он больше не фокусируется на этом представлении, когда фрагмент виден.

В моем случае я должен установить его программно после загрузки данных из API.

Ответ 3

После долгого поиска я посмотрел на параметр reverseLayout, который был установлен в true. Я заменил

horizontalRV.setLayoutManager(
    new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, true));

с

horizontalRV.setLayoutManager(
    new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));

Ответ 4

Попробуйте android:descendantFocusability="blocksDescendants". Он решил проблему для меня.

Ответ 5

Короткий намек на @albertvilacalvo ответ: Если вы программно используете RecyclerView, вы можете обрабатывать setFocusableInTouchMode таким образом (включите в свой класс RecyclerView)

@Override
protected void onAttachedToWindow() {
   ((View) getParent()).setFocusableInTouchMode(true);
   super.onAttachedToWindow();
}

Решение descendantFocusability терпит неудачу, если вам нужно EditText в ваших дочерних представлениях, они больше не будут курсовать. Я использую ListView, настраиваемый (multi) touch и EditText в дочерних элементах RecyclerView. Нет побочных эффектов, использующих setFocusableInTouchMode.

Ответ 6

Инициализируйте менеджер макетов только в oncreate или только 1 раз, не инициализируйте его recyclerview.setLayoutManager(new LinearLayoutManager (context));