В настоящее время я использую следующий код, чтобы проверить, следует ли включить SwipeRefreshLayout.
private void laySwipeToggle() {
if (mRecyclerView.getChildCount() == 0 || mRecyclerView.getChildAt(0).getTop() == 0) {
mLaySwipe.setEnabled(true);
} else {
mLaySwipe.setEnabled(false);
}
}
Но вот в чем проблема. Когда он прокручивается до границы представления другого элемента, mRecyclerView.getChildAt(0).getTop()
также возвращает 0.
Есть что-то вроде RecyclerView.isScrolledToBottom()
или RecyclerView.isScrolledToTop()
?
РЕДАКТИРОВАТЬ: (mRecyclerView.getChildAt(0).getTop() == 0 && linearLayoutManager.findFirstVisibleItemPosition() == 0)
вроде как RecyclerView.isScrolledToTop()
, но как насчет RecyclerView.isScrolledToBottom()
?
android
android-recyclerview
Сарен Артериус
источник
источник
Ответы:
Решение есть в менеджере по расположению.
LinearLayoutManager layoutManager = new LinearLayoutManager(this); // Add this to your Recycler view recyclerView.setLayoutManager(layoutManager); // To check if at the top of recycler view if(layoutManager.firstCompletelyVisibleItemPosition()==0){ // Its at top } // To check if at the bottom of recycler view if(layoutManager.lastCompletelyVisibleItemPosition()==data.size()-1){ // Its at bottom }
РЕДАКТИРОВАТЬ
Если размер вашего элемента больше экрана, используйте следующее, чтобы определить главное событие.
RecyclerView recyclerView = (RecyclerView) view; LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int pos = linearLayoutManager.findFirstVisibleItemPosition(); if(linearLayoutManager.findViewByPosition(pos).getTop()==0 && pos==0){ return true; }
PS: На самом деле, если вы разместите
RecyclerView
непосредственно внутри,SwipeRefreshview
вам не нужно этого делатьисточник
first/lastCompletelyVisibleItemPosition()
вернет -1, подразумевает, что полностью видимого элемента нет вообще.lastVisibleItemPosition
иlastCompletelyVisibleItemPosition
не работают. (невозможно разрешить метод). Помогите?findLastCompletelyVisibleItemPosition
будет НЕОБХОДИМ, если высота последнего элемента больше, чем высота экрана. Это означает, что последний элемент виден, но не полностьюlayout.findLastCompletelyVisibleItemPosition()=-1(RecyclerView.NO_POSITION)
. ИспользованиеlastVisibleItemPosition
и проверка нижней части последнего вида в макете будет безопаснее.Вы можете попробовать
recyclerView.canScrollVertically(int direction)
, если вам просто нужно знать, есть ли прокрутка или нет.Целые числа направления:
источник
onScrollStateChanged
моих работах.Чтобы проверить,
RecyclerView
прокручивается ли вниз. Используйте следующий код./** * Check whether the last item in RecyclerView is being displayed or not * * @param recyclerView which you would like to check * @return true if last position was Visible and false Otherwise */ private boolean isLastItemDisplaying(RecyclerView recyclerView) { if (recyclerView.getAdapter().getItemCount() != 0) { int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition(); if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1) return true; } return false; }
Некоторая дополнительная информация
Если вы хотите реализовать
ScrollToBottom
вRecyclerView
когдаEdittext
есть ,tapped
то я рекомендую вам добавить 1 секундную задержку , как это:edittext.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) if (isLastItemDisplaying(recyclerView)) { // The scrolling can happen instantly before keyboard even opens up so to handle that we add 1 second delay to scrolling recyclerView.postDelayed(new Runnable() { @Override public void run() { recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount() - 1); } }, 1000); } return false; } });
источник
@Saren Артериус, Использование addOnScrollListener из RecycleView , вы можете найти прокрутки в верхней или нижней части вертикального RecycleView , как показано ниже,
RecyclerView rv = (RecyclerView)findViewById(R.id.rv); rv.addOnScrollListener(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) { if (dy < 0) { // Recycle view scrolling up... } else if (dy > 0) { // Recycle view scrolling down... } } });
источник
Используйте recyclerView.canScrollVeretic (int direction), чтобы проверить, достигнута ли верхняя или нижняя часть прокрутки.
direction = 1 для прокрутки вниз (внизу)
direction = -1 для прокрутки вверх (вверху)
если метод возвращает false, это означает, что вы достигли вершины или низа, в зависимости от направления.
источник
Просто сохраните ссылку на свой layoutManager и установите onScrollListener в своем представлении ресайклера, как это
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); visibleItemCount = mRecyclerView.getChildCount(); totalItemCount = mLayoutManager.getItemCount(); firstVisibleItemIndex = mLayoutManager.findFirstVisibleItemPosition(); //synchronizew loading state when item count changes if (loading) { if (totalItemCount > previousTotal) { loading = false; previousTotal = totalItemCount; } } if (!loading) if ((totalItemCount - visibleItemCount) <= firstVisibleItemIndex) { // Loading NOT in progress and end of list has been reached // also triggered if not enough items to fill the screen // if you start loading loading = true; } else if (firstVisibleItemIndex == 0){ // top of list reached // if you start loading loading = true; } } } });
источник
setOnScrollListner
устарел.addOnScrollListener
потому что, как сказал @shajeelAfzal,setOnScrollListener
сейчас устарел, вы должны использовать,addOnScrollListener
потому что, как сказал @shajeelAfzal,setOnScrollListener
сейчас устарел, проверьте здесьpreviousTotal
?Вы можете определить вершину, используя следующие
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if(IsRecyclerViewAtTop()) { //your recycler view reached Top do some thing } } }); private boolean IsRecyclerViewAtTop() { if(recyclerView.getChildCount() == 0) return true; return recyclerView.getChildAt(0).getTop() == 0; }
Это обнаружит вершину, когда вы отпустите палец, когда он достиг вершины, если вы хотите обнаружить, как только reacyclerview достигнет вершины, проверьте метод
if(IsRecyclerViewAtTop())
внутриonScrolled
источник
getChildAt()
возвращает первый дочернийViewGroup
элемент, который может (и будет) отличаться от первого элемента списка. Если этот дочерний элемент окажется идеально выровненным по верхнему краю recyclerview, вашIsRecyclerViewAtTop()
метод вернет true, даже если он не находится сверху.Я написал RecyclerViewHelper, чтобы знать, что recyclerview находится вверху или внизу.
public class RecyclerViewHelper { public static boolean isAtTop(RecyclerView recyclerView) { if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { return isAtTopBeforeIceCream(recyclerView); } else { return !ViewCompat.canScrollVertically(recyclerView, -1); } } private static boolean isAtTopBeforeIceCream(RecyclerView recyclerView) { RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof LinearLayoutManager) { LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager; int pos = linearLayoutManager.findFirstVisibleItemPosition(); if (linearLayoutManager.findViewByPosition(pos).getTop() == recyclerView.getPaddingTop() && pos == 0) return true; } return false; } public static boolean isAtBottom(RecyclerView recyclerView) { if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { return isAtBottomBeforeIceCream(recyclerView); } else { return !ViewCompat.canScrollVertically(recyclerView, 1); } } private static boolean isAtBottomBeforeIceCream(RecyclerView recyclerView) { RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int count = recyclerView.getAdapter().getItemCount(); if (layoutManager instanceof LinearLayoutManager) { LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager; int pos = linearLayoutManager.findLastVisibleItemPosition(); int lastChildBottom = linearLayoutManager.findViewByPosition(pos).getBottom(); if (lastChildBottom == recyclerView.getHeight() - recyclerView.getPaddingBottom() && pos == count - 1) return true; } return false; }
}
источник
ты можешь сделать это, это работа для меня
mRecycleView.addOnScrollListener(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); int topRowVerticalPosition = (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop(); LinearLayoutManager linearLayoutManager1 = (LinearLayoutManager) recyclerView.getLayoutManager(); int firstVisibleItem = linearLayoutManager1.findFirstVisibleItemPosition(); swipeRefreshLayout.setEnabled(firstVisibleItem == 0 && topRowVerticalPosition >= 0); } });
источник
Чтобы узнать, прокручивается ли RecyclerView вниз, вы можете повторно использовать методы, используемые для полосы прокрутки.
Это расчет, для удобства записанный как функция расширения Kotlin:
fun RecyclerView.isScrolledToBottom(): Boolean { val contentHeight = height - (paddingTop + paddingBottom) return computeVerticalScrollRange() == computeVerticalScrollOffset() + contentHeight }
источник
fun RecyclerView.isScrolledToBottom(margin: Int = 1): Boolean { val contentHeight = height - (paddingTop + paddingBottom) return computeVerticalScrollRange() - computeVerticalScrollOffset() - contentHeight >= margin }
fun RecyclerView.isScrolledToBottom(margin: Int = 1): Boolean { val contentHeight = height - (paddingTop + paddingBottom) return computeVerticalScrollRange() - computeVerticalScrollOffset() - contentHeight <= margin }
вы можете попробовать с OnTouchListener:
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_UP || e.getAction() == MotionEvent.ACTION_MOVE){ if (mLinearLayoutManager.findFirstCompletelyVisibleItemPosition() > 0) { // beginning of the recycler } if (mLinearLayoutManager.findLastCompletelyVisibleItemPosition()+1 < recyclerView.getAdapter().getItemCount()) { // end of the recycler } } return false; }
источник