Как узнать, прокручивается ли RecyclerView/LinearLayoutManager сверху или снизу?
В настоящее время я использую следующий код, чтобы проверить, разрешено ли 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.
![The problem]()
Есть ли что-то вроде RecyclerView.isScrolledToBottom()
или RecyclerView.isScrolledToTop()
?
EDIT: (mRecyclerView.getChildAt(0).getTop() == 0 && linearLayoutManager.findFirstVisibleItemPosition() == 0)
вид RecyclerView.isScrolledToTop()
, но как насчет RecyclerView.isScrolledToBottom()
?
Ответы
Ответ 1
Решение в менеджере раскладки.
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
вам не нужно будет делать это
Ответ 2
Вы можете попробовать recyclerView.canScrollVertically(int direction)
, если вам просто нужно знать, возможна ли прокрутка или нет.
Направление целых чисел:
- -1 наверх
- 1 для пуха
- 0 всегда будет возвращать ложь.
Ответ 3
Чтобы проверить, прокручивается ли 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;
}
});
Ответ 4
@Saren Arterius, используя 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...
}
}
});
Ответ 5
Просто держите ссылку на свой 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;
}
}
}
});
Ответ 6
Используйте recyclerView.canScrollVertically(int direction), чтобы проверить, достигли ли верх или низ прокрутки.
направление = 1 для прокрутки вниз (внизу)
направление = -1 для прокрутки вверх (вверх)
Если метод возвращает false, это означает, что вы достигли вершины или вершины, зависит от направления.
Ответ 7
Вы можете определить верхнюю часть с помощью следующих
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
Ответ 8
Я написал 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;
}
}
Ответ 9
вы можете это сделать для меня
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);
}
});
Ответ 10
вы можете попробовать с помощью 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;
}
Ответ 11
Используйте следующий простой код, чтобы определить, достиг ли RecyclerView сверху или снизу:
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager.canScrollVertically()) {
// ehh ehh
} else {
// you can use swipe-to-refresh
}
Ответ 12
Чтобы выяснить, прокручивается ли RecyclerView вниз, вы можете повторно использовать методы, используемые для полосы прокрутки.
Это расчет, для удобства записанный как функция расширения Kotlin:
fun RecyclerView.isScrolledToBottom(): Boolean {
val contentHeight = height - (paddingTop + paddingBottom)
return computeVerticalScrollRange() == computeVerticalScrollOffset() + contentHeight
}