如何知道一个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。
有没有像RecyclerView.isScrolledToBottom()
或RecyclerView.isScrolledToTop()
?
编辑: (mRecyclerView.getChildAt(0).getTop() == 0 && linearLayoutManager.findFirstVisibleItemPosition() == 0)
RecyclerView.isScrolledToTop()
种类,但RecyclerView.isScrolledToBottom()
呢?
解决scheme是在布局pipe理器中。
LinearLayoutManager layoutManager=new LinearLayoutManager(this); //Add this to your Recyclerview recyclerview.setLayoutManager(layoutManager); //Tocheck if recycler is on top if(layoutManager.firstCompletelyVisibleItemPosition()==0){ //Its at top .. } //Tocheck if recycler is on bottom if(layoutManager.lastCompletelyVisibleItemPosition()==data.size()-1){ //Its at bottom .. }
编辑如果您的项目尺寸大于屏幕,请使用以下内容来检测顶部事件。
RecyclerView rc=(RecyclerView)view; LinearLayoutManager lm= (LinearLayoutManager) rc.getLayoutManager(); int pos = lm.findFirstVisibleItemPosition(); if(lm.findViewByPosition(pos).getTop()==0 && pos==0) return true;
PS:实际上,如果您将RecyclerView直接放入SwipeRefreshView中,则不需要执行此操作
你可以尝试recyclerView.canScrollVertically(int direction)
,如果你只是需要知道是否可以滚动或不
为了检查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; }
一些附加信息
如果你想在RecyclerView
实现ScrollToBottom
,那么我build议你添加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 Arterius,使用RecycleView的addOnScrollListener ,可以像下面一样findVertical 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... } } });
只需保持对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; } } } });
你可以做到这一点对我来说是工作
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); } });
你可以尝试使用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; }
我已经写了一个RecyclerViewHelper知道回收站是在顶部还是在底部。
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; }
}
您可以使用以下方法检测top
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; }
这将检测到顶部,当你释放手指一旦到达顶部,如果你想尽快检测到reacherclerview顶部检查if(IsRecyclerViewAtTop())
里面的onScrolled
方法