概述
最近项目中遇到一个坑,正好可以总结一下:
将RecyclerView滑动到指定位置,或者检索RecyclerView的某一项(各个项的高度不确定),然后定位滚动这到一项,将它显示。
下面就讲解4种RecyclerView定位滚动的方式及具体效果演示。
scrollBy
@Override
public void scrollBy(int x, int y) {
if (mLayout == null) {
Log.e(TAG, "Cannot scroll without a LayoutManager set. "
+ "Call setLayoutManager with a non-null argument.");
return;
}
if (mLayoutSuppressed) {
return;
}
final boolean canScrollHorizontal = mLayout.canScrollHorizontally();
final boolean canScrollVertical = mLayout.canScrollVertically();
if (canScrollHorizontal || canScrollVertical) {
scrollByInternal(canScrollHorizontal ? x : 0, canScrollVertical ? y : 0, null,
TYPE_TOUCH);
}
}
使用:recyclerView.scrollBy(x, y)
scrollBy(x, y)
这个方法是自己去控制移动的距离,单位是像素,所以在使用scrollBy(x, y)
需要自己去计算移动的高度或宽度。
scrollToPosition
/** 方便的方法滚动到一定的位置。RecyclerView不实现滚动逻辑,而是转发调用RecyclerView.
* layoutmanager . scrolltopposition (int) Params: position滚动到这个适配器的位置参
*/ 见:RecyclerView. layoutmanager . scrolltopposition (int)
public void scrollToPosition(int position) {
if (mLayoutSuppressed) {
return;
}
stopScroll();
if (mLayout == null) {
Log.e(TAG, "Cannot scroll to position a LayoutManager set. "
+ "Call setLayoutManager with a non-null argument.");
return;
}
mLayout.scrollToPosition(position);
awakenScrollBars();
}
recyclerView.scrollToPosition(position)
使用: recyclerView.scrollToPosition(position)
scrollToPosition(position)
这个方法的作用是定位到指定项,就是把你想显示的项显示出来,但是在屏幕的什么位置是不管的,只要那一项现在看得到了,那它就罢工了!
smoothScrollToPosition
/** 平滑滚动到指定的适配器位置。为了支持平滑滚动,覆盖这个方法,创建你的RecyclerView
* SmoothScroller实例并调用startSmoothScroll(RecyclerView.SmoothScroller)
* 参数:recyclerView,个布局管理器所连接的recyclerView的当前状态。
*/
public void smoothScrollToPosition(RecyclerView recyclerView, State state,
int position) {
Log.e(TAG, "You must override smoothScrollToPosition to support smooth scrolling");
}
recyclerView.smoothScrollToPosition(position)
使用: recyclerView.smoothScrollToPosition(position)
smoothScrollToPosition(position)
和scrollToPosition(position)
效果基本相似,也是把你想显示的项显示出来,只要那一项现在看得到了,那它就罢工了,不同的是smoothScrollToPosition是平滑到你想显示的项,而scrollToPosition是直接定位显示!
scrollToPositionWithOffset
/** 从解析的布局开始以给定偏移量滚动到指定的适配器位置。解析的布局开始依赖于getReverseLayout().
* ViewCompat.getLayoutDirection(View)和getStackFromEnd()。例如,如果布局是VERTICAL和
* getStackFromEnd()为真,调用scrollToPositionWithOffset(10,20)将布局这样项目[10]的底部20
* 像素以上的RecyclerView的底部。注意,滚动位置的变化直到下一次布局调用才会反映出来。如果您只是图
* 使位置可见,请使用scrolltopposition (int)。参数:position引用项的索引(从0开始)。offset项目
* 视图的起始边缘和RecyclerView的起始边缘之间的距离(以像素为单位)。参
* 见:setReverseLayout(boolean),
* scrolltopposition (int)
*/
public void scrollToPositionWithOffset(int position, int offset) {
mPendingScrollPosition = position;
mPendingScrollPositionOffset = offset;
if (mPendingSavedState != null) {
mPendingSavedState.invalidateAnchor();
}
requestLayout();
}
scrollToPositionWithOffset(position,0)
使用: ((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(position,0);
主角总是最后才登场,这种方式是定位到指定项如果该项可以置顶就将其置顶显示。比如:微信联系人的字母索引定位就是采用这种方式实现。