RecycleView的定位滚动解析与实战

1,456 阅读2分钟

概述

最近项目中遇到一个坑,正好可以总结一下:
将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);
    }
}

image.png

使用: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();
}

image.png

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");
}

image.png

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();
}

image.png

scrollToPositionWithOffset(position,0)

使用: ((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(position,0);

主角总是最后才登场,这种方式是定位到指定项如果该项可以置顶就将其置顶显示。比如:微信联系人的字母索引定位就是采用这种方式实现。