Intereting Posts
Что лучше использовать, массив hardcoded array или resource string? Пользовательский шрифт TrueType только от xml Как использовать цветные образцы для Android Android-7.0: EditText неправильный actionId в редакторе actionlistener Программно получить данные об использовании сети для каждого тега на Android Android: Можно ли отображать миниатюры видео? Что я должен использовать для повышения производительности, с девятью патчами или ресурсом xml? Как заменить устаревший android.support.v4.app.ActionBarDrawerToggle Интернет-проверка, где разместить при использовании MVP, RX и дооснащение Как я могу получить доступ к элементам, возвращаемым функцией KeyCharacterMap.getEvents из Delphi? Каково использование методов setDoOutput и setDoInput класса HttpURLConnection Как сделать анимированный анимированный андроид? Темы в Android? Проблема на Android 6.0.1 «Неустранимое исключение: android.view.WindowManager $ BadTokenException» Equalizer.usePreset throws Недопустимое исключение аргумента

Прокрутка фокуса RecyclerView

У меня есть RecyclerView, обычно два столбца и до восьми. Мы используем много навигации D-PAD. У нас проблема при прокрутке, сфокусированный предмет будет прыгать слева направо. Смотрите фотографии: Введите описание изображения здесь

Я заметил, что если элементы, которые появляются дальше, кэшируются, при прокрутке проблем с фокусом не возникает. Еще одна проблема, с которой я столкнулся, – это мой фокус, который может появиться ниже моего липкого заголовка. Это нежелательно. Поэтому мне кажется, что если бы я сделал это, то при прокрутке у него был бы «порог». Таким образом, когда фокус находится в пределах одного элемента вне экрана, он будет прокручиваться. Таким образом, фокус никогда не находится на самом дне, или на самом верху.

Имея это в виду, я пробовал этот подход без везения:

RecyclerView rv; @Override public void onFocusChange(View v, boolean hasFocus) { if(!v.hasFocus()) { Log.w(TAG, "View v did not have focus"); return; } final int index = rv.getChildPosition(v); //adapter pos if(index == NO_POSITION) { Log.w(TAG, "Recycler view did not have view"); return; } int position = rv.indexOfChild(v); // layout pos int lastPos = rv.getChildCount(); // layout pos int span = getLayoutManager().getSpanCount(); int threshold = 2 * span; Log.d(TAG, String.format("Position: %1$d. lastPos: %2$d. span: %3$d. threshold: %4$d", position, lastPos, span, threshold)); if (position >= (lastPos - threshold)) { //scroll down if possible int bottomIndex = rv.getChildPosition(rv.getChildAt(lastPos)); if (bottomIndex < getItemCount()) { //scroll down int scrollBy = v.getHeight(); recycler.scrollBy(0, scrollBy); Log.d(TAG, String.format("Scrolling down by %d", scrollBy)); } } else if (position <= threshold) { //scroll up if possible int topIndex = rv.getChildPosition(rv.getChildAt(0)); if (topIndex > 0) { //scroll up int scrollBy = v.getHeight(); recycler.scrollBy(0, -scrollBy); Log.d(TAG, String.format("Scrolling up by %d", -scrollBy)); } } } 

Я открыт для любых идей о том, как управлять фокусом при прокрутке.

Я сообщил об этой ошибке для трекера AOSP: вопрос 190526

Как я вижу из источника, проблема LinearLayoutManager с тем, что GridLayoutManager использует реализацию onFocusSearchFailed() которая вызывается, когда фокус приближается к внутренней границе RecyclerView . LinearLayoutManager предлагает только первый / последний (зависит от направления прокрутки). Следовательно, фокус переходит к первому / последнему элементу новой строки.

Мое обходное решение для этой проблемы .