Intereting Posts
Как разрешить «Дублировать файлы, скопированные в APK META-INF / *» Не удалось создать библиотеку поддержки на Travis CI / Android SDK v20 Android savedInstanceState всегда null CalledFromWrongThreadException: только исходный поток, создавший иерархию представления, может касаться представлений Android EditText AutoFocus для следующего EditText, когда на maxlength Захват подписи для android с помощью телефонной заставки Как импортировать модуль без создания копии в Android Studio Правильное место для размещения mp3-файлов в проекте Android Android Spinner Размер очень большой Матричные преобразования OpenGL ES Android MP android chart, отображающая значения поплавка при X-оси горизонтальной диаграммы? Стиль Android-ресурсов Компилирует (aapt): неудачная таблица ресурсов: размер заголовка 0xc Блокировка будильника AlarmManager при запуске службы Переопределение панели контекстных действий по умолчанию для выбора текста (в WebView) на Android ContextCompat.GetColor не возвращает цвет

RecyclerView scrollToPosition не запускает scrollListener

Я использую RecyclerView, с ScrollListener:

mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // Do my logic } }); 

Когда я прокручиваю пальцем, прослушиватель прокрутки срабатывает нормально.

Но когда я прокручиваю прогрессивно, вот так:

 mRecyclerView.scrollToPosition(LAST_POSITION); 

Слушатель прокрутки не запускается.

Solutions Collecting From Web of "RecyclerView scrollToPosition не запускает scrollListener"

Это известная проблема. Это вызвано тем фактом, что RecyclerView не знает, как LayoutManager будет обрабатывать свиток или если он будет обрабатывать его вообще.

В следующем выпуске вы получите вызов onScrolled если первая и последняя onScrolled позиция будут изменены после макета (что обычно является результатом вызова прокрутки в позицию).

К сожалению, dx и dy будут scrollTo 0, потому что RecyclerView действительно не знает, сколько макетов было scrollTo для обработки запроса scrollTo . Кроме того, вы также можете использовать обратный вызов прокрутки ViewTreeObserver.

Я столкнулся с той же проблемой и нашел обходное решение, которое должно использовать smoothScrollToPosition в менеджере компоновки. Этот метод запускает прослушиватель прокрутки. Так что в основном это то, что я использую:

 recyclerView.scrollToPosition(recyclerAdapter.getItemCount() - 1); 

И теперь я изменил это:

 recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, recyclerAdapter.getItemCount() - 1); 

И он отлично работает для меня.

Это немного рудиментарно, но вы можете попробовать этот подкласс RecyclerView:

 public class PatchedRecyclerView extends RecyclerView { private OnScrollListener listener; public PatchedRecyclerView(Context context) { super(context); } public PatchedRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public PatchedRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setOnScrollListener(OnScrollListener listener) { super.setOnScrollListener(listener); this.listener = listener; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int preFirstChildPosition = getChildCount() != 0 ? getChildViewHolder(getChildAt(0)).getPosition() : -1; int preLastChildPosition = getChildCount() != 0 ? getChildViewHolder(getChildAt(getChildCount() - 1)).getPosition() : -1; super.onLayout(changed, l, t, r, b); int postFirstChildPosition = getChildCount() != 0 ? getChildViewHolder(getChildAt(0)).getPosition() : -1; int postLastChildPosition = getChildCount() != 0 ? getChildViewHolder(getChildAt(getChildCount() - 1)).getPosition() : -1; // TODO: Insert proper DX and DY values if (preFirstChildPosition != postFirstChildPosition || preLastChildPosition != postLastChildPosition) listener.onScrolled(this, 0, 0); } } 
 int mFirst=0, mLast=0; recyclerview.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); LinearLayoutManager llm = (LinearLayoutManager) recyclerview.getLayoutManager(); mLast = llm.findLastCompletelyVisibleItemPosition(); mFirst = llm.findFirstCompletelyVisibleItemPosition(); } }); imgRight.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LinearLayoutManager llm = (LinearLayoutManager) recyclerview.getLayoutManager(); llm.scrollToPositionWithOffset(mLast + 1, List.length()); } }); imgLeft.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LinearLayoutManager llm = (LinearLayoutManager) recyclerview.getLayoutManager(); llm.scrollToPositionWithOffset(mFirst - 1, List.length()); } }); 

Чтобы явно вызвать onScrollListener по представлению ресайклера, используйте:

 recyclerView.smoothScrollBy(x, y); //x is the horizontal displacement and y is vertical displacement. 

Я не мог использовать smoothScrollToPosition (у нас были некоторые проблемы с ним в прошлом), и в зависимости от позиции первого элемента казалось ненадежным, поэтому я закончил использовать ответ yigit (он уже выпущен), к сожалению, Всегда работаю (я не уверен, почему).

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

Переопределить RecyclerView:

 public class MyRecyclerView extends RecyclerView { public interface OnScrollStoppedListener{ void onScrollStopped(); } private static final int NEW_CHECK_INTERVAL = 100; private OnScrollStoppedListener mOnScrollStoppedListener; private Runnable mScrollerTask; private int mInitialPosition; public MyRecyclerView(Context context) { super(context); init(); } public MyRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mScrollerTask = new Runnable() { public void run() { int newPosition = getScrollY(); if(mInitialPosition - newPosition == 0) {//has stopped if(mOnScrollStoppedListener !=null) { mOnScrollStoppedListener.onScrollStopped(); } } else { startScrollerTask(); } } }; } public void setOnScrollStoppedListener(MyRecyclerView.OnScrollStoppedListener listener){ mOnScrollStoppedListener = listener; } public void startScrollerTask() { mInitialPosition = getScrollY(); postDelayed(mScrollerTask, NEW_CHECK_INTERVAL); } } 

Применение:

 myRecyclerView.setOnScrollStoppedListener(new MyRecyclerView.OnScrollStoppedListener() { @Override public void onScrollStopped() { // Do your thing } }); myRecyclerView.startScrollerTask(); 

Muito legal seu conselho.

  Button maisOpcoes = (Button) findViewById(R.id.maisOpcoes); maisOpcoes.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null , recyclerViewTmd.getItemCount() - 1); maisOpcoes.setVisibility(View.GONE); } });