RecyclerView 滑动到指定位置的终极方案

Posted 徐昊Xiho

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RecyclerView 滑动到指定位置的终极方案相关的知识,希望对你有一定的参考价值。

最近有个奇葩需求,顶部有可以切换的 TabLayout,原本下面用 ViewPager 实现,可以左右滑动,后来说需求根据用户切换 Tab 定位到相应的位置,(个人感觉体验不是很好,用户还得用手去点tab),无奈只好改了,我记RecyclerView 有个smoothScrollToPosition(position) 可以实现定位功能,我加了上去之后效果非常差,有时候还不滚动,后来查了一些资料,使用这个方法是有问题的,

需要分情况处理:

  • 跳转位置在第一个可见位置之前,使用smoothScrollToPosition
  • 跳转位置在第一个可见位置之后,最后一个可见项之前
  • 跳转位置在最后可见项之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置

要分为以上三种情况,最终通过smoothScrollToPosition结合smoothScrollBy实现,直接贴伪代码如下:

—— 注释部分代码是属于业务逻辑功能,可忽视

   /**
     * 移动到对应的位置
     *
     * @param position tab 的下标
     */
    private void move(int position) 
//        String proMenuId = proMenuBeans.get(position).getId();
//        LogUtils.d("proMenuId:" + proMenuId);
//        //体系列表的下标
//        int index = 0;
//        for (SystemBean systemBean : systemList) 
//            if (systemBean.getProjectid().equals(proMenuId)) 
//                LogUtils.d("systemList Id:" + systemBean.getProjectid());
//                index = systemList.indexOf(systemBean);
//                LogUtils.d("systemList Index" + index);
//            
//        
//        LogUtils.d("list 中 索引的位置:" + index);


        smoothMoveToPosition(mRecyclerView, index);



    
  • 滑动到指定位置:
 //目标项是否在最后一个可见项之后
    private boolean mShouldScroll;
    //记录目标项位置
    private int mToPosition;

    /**
     * 滑动到指定位置
     */
    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) 
            // 第二种可能:跳转位置在第一个可见位置之后,最后一个可见项之前
            int movePosition = position - firstItem;
            if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) 
                int top = mRecyclerView.getChildAt(movePosition).getTop();
                // smoothScrollToPosition 不会有效果,此时调用smoothScrollBy来滑动到指定位置
                mRecyclerView.smoothScrollBy(0, top);
            
         else 
            // 第三种可能:跳转位置在最后可见项之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
            // 再通过onScrollStateChanged控制再次调用smoothMoveToPosition,执行上一个判断中的方法
            mRecyclerView.smoothScrollToPosition(position);
            mToPosition = position;
            mShouldScroll = true;
        
    
  • 再通过监听 RecyclerView 的滑动事件,控制再次调用smoothMoveToPosition。

        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() 
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) 
                super.onScrollStateChanged(recyclerView, newState);
                if (mShouldScroll && RecyclerView.SCROLL_STATE_IDLE == newState) 
                    mShouldScroll = false;
                    smoothMoveToPosition(mRecyclerView, mToPosition);
                
            
        );

以上就是伪代码,很简单,完美解决了我们遇到的问题,OK去试试吧~~

以上是关于RecyclerView 滑动到指定位置的终极方案的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView滑动到指定位置,并置顶

Android RecyclerView 滑动到指定位置 RecyclerView 滑动到顶部

Android-RecyclerView系列 滑动到指定位置

android recyclerview 是不是能上滑动

使用 ItemTouchHelper 在 recyclerView 中滑动到另一个视图

Android-RecyclerView系列 RecyclerView滚动指定位置到屏幕中间