自定义 LayoutManager 实现 RecyclerView 列表点击定位到中间位置

3,391 阅读1分钟

通过自定义 LayoutManager ,可以让 RecyclerView 列表实现,当点击任意一个 item 时,可以让此 item 定位到中间位置。

效果图

效果图

解决参考: stackoverflow

开发起因

公司的机票日历模块需求:横向滑动的日历,展示 7 天的价格,一共 15 天的价格,点击任意一天,如果不是前 3 天或者后 3 天,要求点击的那一天定位在列表的正中间。

一般情况下,RecyclerView 的列表滚动到指定位置,我们会使用 RecyclerView 的 smoothScrollToPosition(),但是问题有两个:

  1. 不会定位到中间位置。
  2. 当滚动的目标位置在屏幕中时,不会滚动。

第一个问题通过一系列的计算终于是解决了,可第二个,无论怎么做都无法解决。 翻遍所有文章,还是 stackoverflow 靠谱!

解决方法

  1. 新建 CenterLayoutManager 类继承 LinearLayoutManager 类,重写 smoothScrollToPosition() 方法。

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        // CenterSmoothScroller 我们自定义的 SmoothScroller
        RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }
    
  2. 在此类中,新建 CenterSmoothScroller 类继承 LinearSmoothScroller 类,重写 calculateDtToFit() 方法。

    @Override
    public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
        return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
    }
    

在使用时,设置 CenterLayoutManager 为 RecyclerView 的 LayoutManager, 正常调用 smoothScrollToPosition() 方法就可以轻松实现点击 item 使 item 定位到列表中间的功能了。是不是很简单?

有兴趣的小伙伴可以深入仔细研究这几个类,小编能力有限,就先把砖抛到这里了。

整体代码见 GitHub 链接地址