Obecnie używam poniższego kodu, aby sprawdzić, czy SwipeRefreshLayout powinno być włączone.
private void laySwipeToggle() {
if (mRecyclerView.getChildCount() == 0 || mRecyclerView.getChildAt(0).getTop() == 0) {
mLaySwipe.setEnabled(true);
} else {
mLaySwipe.setEnabled(false);
}
}
Ale tu jest problem. Po przewinięciu do granicy widoku innego elementu mRecyclerView.getChildAt(0).getTop()
również zwraca 0.
Czy jest coś takiego jak RecyclerView.isScrolledToBottom()
lub RecyclerView.isScrolledToTop()
?
EDYCJA: (mRecyclerView.getChildAt(0).getTop() == 0 && linearLayoutManager.findFirstVisibleItemPosition() == 0)
niby robi RecyclerView.isScrolledToTop()
, ale o co chodzi RecyclerView.isScrolledToBottom()
?
android
android-recyclerview
Saren Arterius
źródło
źródło
Odpowiedzi:
Rozwiązanie znajduje się w menedżerze układu.
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 }
EDYTOWAĆ
Jeśli rozmiar twojego przedmiotu jest większy niż ekran, użyj poniższych, aby wykryć największe zdarzenie.
RecyclerView recyclerView = (RecyclerView) view; LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int pos = linearLayoutManager.findFirstVisibleItemPosition(); if(linearLayoutManager.findViewByPosition(pos).getTop()==0 && pos==0){ return true; }
PS: Właściwie, jeśli umieścisz
RecyclerView
bezpośrednio w środkuSwipeRefreshview
, nie musisz tego robićźródło
first/lastCompletelyVisibleItemPosition()
zwróci -1, oznacza, że nie ma w pełni widocznej pozycji.lastVisibleItemPosition
ilastCompletelyVisibleItemPosition
nie działają. (nie można rozwiązać metody). Wsparcie?findLastCompletelyVisibleItemPosition
nie powiedzie się, jeśli wysokość ostatniego elementu jest większa niż wysokość ekranu. Oznacza to, że ostatni element jest widoczny, ale nie do końca widoczny, więclayout.findLastCompletelyVisibleItemPosition()=-1(RecyclerView.NO_POSITION)
.lastVisibleItemPosition
Bezpieczniejsze będzie używanie i sprawdzanie dolnej części ostatniego widoku w układzie.Możesz spróbować
recyclerView.canScrollVertically(int direction)
, jeśli chcesz tylko wiedzieć, czy można przewijać, czy nie.Liczby całkowite kierunku:
źródło
onScrollStateChanged
pracy dla mnie.Aby sprawdzić, czy
RecyclerView
jest przewijany do dołu. Użyj poniższego kodu./** * 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; }
Kilka dodatkowych informacji
Jeśli chcesz wprowadzić
ScrollToBottom
wRecyclerView
gdyEdittext
jesttapped
to polecam dodać 1 sekundowe opóźnienie tak: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; } });
źródło
@Saren Arterius, używając addOnScrollListener z RecycleView , możesz znaleźć przewijaną górę lub dół Vertical RecycleView, jak poniżej,
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... } } });
źródło
Użyj recyclinglerView.canScrollVertically (int direction), aby sprawdzić, czy osiągnięto górną lub dolną część zwoju.
direction = 1 dla przewijania w dół (na dole)
direction = -1 dla przewijania w górę (do góry)
jeśli metoda zwraca false, oznacza to, że dotarłeś do góry lub do dołu, w zależności od kierunku.
źródło
Po prostu zachowaj odniesienie do swojego layoutManagera i ustaw onScrollListener w widoku recyklera w ten sposób
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; } } } });
źródło
setOnScrollListner
jest teraz przestarzała.addOnScrollListener
ponieważ, jak powiedział @shajeelAfzal,setOnScrollListener
jest teraz przestarzałe, powinieneś używać,addOnScrollListener
ponieważ, jak powiedział @shajeelAfzal,setOnScrollListener
jest teraz przestarzałe, sprawdź tutajpreviousTotal
?Możesz wykryć górę, używając następującego
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; }
Spowoduje to wykrycie góry, gdy zwolnisz palec po osiągnięciu górnej części, jeśli chcesz wykryć, gdy tylko ponownie przegląd osiągnie górę, sprawdź metodę
if(IsRecyclerViewAtTop())
wewnątrzonScrolled
źródło
getChildAt()
zwraca pierwsze dziecko elementuViewGroup
, które może (i będzie) różnić się od pierwszego elementu listy. Jeśli zdarzy się, że to dziecko jest idealnie wyrównane z górną częścią widoku recyklingu, TwojaIsRecyclerViewAtTop()
metoda zwróci wartość true, nawet jeśli nie znajduje się na górze.Napisałem RecyclerViewHelper, aby wiedzieć, że widok recyklingu jest na górze lub na dole.
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; }
}
źródło
możesz to zrobić, to praca dla mnie
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); } });
źródło
Aby dowiedzieć się, czy widok RecyclerView jest przewijany do dołu, możesz ponownie użyć metod używanych dla paska przewijania.
Oto obliczenia dla wygody zapisane jako funkcja rozszerzenia Kotlina:
fun RecyclerView.isScrolledToBottom(): Boolean { val contentHeight = height - (paddingTop + paddingBottom) return computeVerticalScrollRange() == computeVerticalScrollOffset() + contentHeight }
źródło
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 }
możesz spróbować z 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; }
źródło