100 行代码写一个可滑动、可回收的 LayoutManager

实现的效果是这样的:



滑动效果非常流畅。一共 50 个 item,只创建了5个 ViewHolder,做到了复用。

实现一个这样的 LayoutManager 需要做到三点:

    初始布局:在 onLayoutChildren 里根据 position 从 Recycler 的 getViewForPosition 方法里获取子 View,调用 measureChild 测量它们,计算坐标并调用 layoutDecorated 布局,最后添加到 RecyclerView。为了复用,在这个阶段只需要获取足够当前显示的子 View。

    滑动:重写 canScrollHorizontally 或 canScrollVertically 返回 true 。再重写 scrollHorizontallyBy 或 scrollVerticallyBy 接收 RecyclerView 传来的 dx 或 dy 。在一次滑动中, dx 是通过 old x - new x 计算出来的, 所以 item 向左滑 dx 会大于 0,向右滑会小于 0 。 dy 也是一样。 因为向左滑 dx 是大于 0 的,为了让子 View 往左滑(在坐标系 x 轴上越来越接近 0),在使用这个 dx 或 dy 时 要对它进行取反。调用 offsetChildrenHorizontal 或 offsetChildrenVertical 让当前所有 RecyclerView 的子 View 进行移动。

    复用:在进行滑动时,左边或右边会出现一些空白,我们通过 getViewForPosition 获取之前或之后的 View, 然后测量、布局并添加为 RecyclerView 的子 View, 填充这块空白区域。如果只是这样做,getViewForPosition 每次都会调用 onCreateViewHolder 创建一个新 View 返回给我们。为了做到 View 的复用,我们需要把不在当前屏幕显示的 View 及时回收。通过调用 removeAndRecycleView 移除并回收 View。getViewForPosition 会先从已被回收的 View 中查找需要返回的 View。

另外在滑动时还需要进行边界检测。

代码在这里

你可能感兴趣的:(100 行代码写一个可滑动、可回收的 LayoutManager)