RecyclerView跳转到指定位置的三种方式

时间:2024-03-17 22:18:03

自从android5.0推出RecyclerView以后,RecyclerView越来越受广大程序员的热爱了!大家都知道RecyclerView的出现目的是为了替代listview和ScrollView在列表方面的使用!那么listview和ScrollView的所有功能和方法都应该有的!

但是RecyclerView的很多方法,不是封装在RecyclerView中的,当我们在RecyclerView中找不到对应的方法时,就应该想到他的管理类manager了! 
大多方法都封装在此啊!

最近有个同学用到了RecyclerView跳转到指定位置的需求,其实很简单,在这里我就给出我的做法,有指教的和改进的欢迎提出,需要用的就用,勿喷哈…..

方法一,直接使用当前的manager

  /**
     * RecyclerView 移动到当前位置,
     *
     * @param manager  设置RecyclerView对应的manager
     * @param n  要跳转的位置
     */
    public static void MoveToPosition(LinearLayoutManager manager, int n) {
        manager.scrollToPositionWithOffset(n, 0);
        manager.setStackFromEnd(true);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

方法二、根据当前RecyclerView的条目数量,这个相对复杂一些,但是可以有效地避免指针越界呦..

/**
 * RecyclerView 移动到当前位置,
 *
 * @param manager   设置RecyclerView对应的manager
 * @param mRecyclerView  当前的RecyclerView
 * @param n  要跳转的位置
 */
public static void MoveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) {


    int firstItem = manager.findFirstVisibleItemPosition();
    int lastItem = manager.findLastVisibleItemPosition();
    if (n <= firstItem) {
        mRecyclerView.scrollToPosition(n);
    } else if (n <= lastItem) {
        int top = mRecyclerView.getChildAt(n - firstItem).getTop();
        mRecyclerView.scrollBy(0, top);
    } else {
        mRecyclerView.scrollToPosition(n);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 方法三:带有滚动效果
  /**
     * 目标项是否在最后一个可见项之后
     */
    private boolean mShouldScroll;
    /**
     * 记录目标项位置
     */
    private int mToPosition;

    /**
     * 滑动到指定位置
     *
     * @param mRecyclerView
     * @param position
     */
    private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
        // 第一个可见位置
        int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
        // 最后一个可见位置
        int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));

        if (position < firstItem) {
            // 如果跳转位置在第一个可见位置之前,就smoothScrollToPosition可以直接跳转
            mRecyclerView.smoothScrollToPosition(position);
        } else if (position <= lastItem) {
            // 跳转位置在第一个可见项之后,最后一个可见项之前
            // smoothScrollToPosition根本不会动,此时调用smoothScrollBy来滑动到指定位置
            int movePosition = position - firstItem;
            if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
                int top = mRecyclerView.getChildAt(movePosition).getTop();
                mRecyclerView.smoothScrollBy(0, top);
            }
        } else {
            // 如果要跳转的位置在最后可见项之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
            // 再通过onScrollStateChanged控制再次调用smoothMoveToPosition,执行上一个判断中的方法
            mRecyclerView.smoothScrollToPosition(position);
            mToPosition = position;
            mShouldScroll = true;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
 mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (mShouldScroll) {
                    mShouldScroll = false;
                    smoothMoveToPosition(mRecyclerView, mToPosition);
                }
            }
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  if (TextUtils.equals(mCarBrandList.get(i).pinyin.charAt(0) + "", letter)) {
                        if (i == 0) {
//                            UIUtils.MoveToPosition(manager, mRecyclerView, i);
                            smoothMoveToPosition(mRecyclerView,i);
                        } else {
                            smoothMoveToPosition(mRecyclerView,i+1);
//                            UIUtils.MoveToPosition(manager, mRecyclerView, i + 1);
                        }
                        break;
                    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

好了这样就可以了,不信你试试…….