Intereting Posts
Разработка Android: «поток, выходящий с неперехваченным исключением» Как вычисляется значение плотности в android C2DM с PHP с использованием OAuth2.0 (ClientLogin устарел!) Автоматически отображать пользовательскую клавиатуру для EditText. Android Проект библиотеки Android com.android.dex.DexException: несколько файлов dex определяют Lcom / google / gson / JsonSerializer Нет регистрации в Commons в Android? Android Audio – Потоковое синусоидальное генераторное поведение Проблемы с созданием библиотеки Android с собственным кодом Предоставляет ли GoogleAccountCredential токен обновления? Как отслеживать изменение состояния SIM-карты Доступность и Android WebView TabLayout не заполняет ширину, когда tabMode установлен на "прокручиваемый" Сглаженная очень медленная текстовая анимация на холсте Android, SUBPIXEL_TEXT_FLAG не работает Android: получение списка приложений для устройств – очень медленно Unity 3d – Физический класс для участия

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); 

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

Это известная проблема. Это вызвано тем фактом, что 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); } });