RecycleView ItemDecoration 自定义绘制

仓库地址 https://gitee.com/BigObj/bo-an-poj-common

通过给 RecycleView add ItemDecoration 设置 item 上下左右间距

自定义 RecyclerView.ItemDecoration

重写 getItemOffsets 给间距赋值

重写 onDraw 将 需要填充在间距中的 drawable 绘制出来

模型

class ItemSpace {

    /**
     * 上间隔填充
     */
    var topDrawable: Drawable? = null

    /**
     * 下间隔填充
     */
    var bottomDrawable: Drawable? = null

    /**
     * 设置item上下左右间隔尺寸
     */
    val rect: Rect by lazy {
        Rect(0, 0, 0, 0)
    }

    /**
     * 上填充间隔 的 margin
     */
    val topDrawableMargin: Rect by lazy {
        Rect(0, 0, 0, 0)
    }

    /**
     * 下填充间隔 的 margin
     */
    val bottomDrawableMargin: Rect by lazy {
        Rect(0, 0, 0, 0)
    }
}

实现

class RecyclerItemDecoration(private var spaceArray: SparseArray): RecyclerView.ItemDecoration() {

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        val left = parent.left
        val right = parent.right
        val childCount = parent.childCount

        // 遍历所有展示的 itemView 为其添加上下填充视图
        for (i in 0 until childCount) {
            val view = parent.getChildAt(i)
            val viewHolder = parent.getChildViewHolder(view)
            val itemSpace = spaceArray[viewHolder.itemViewType]

            // 绘制上间隔填充物
            itemSpace?.topDrawable?.setBounds(
                left + itemSpace.topDrawableMargin.left + itemSpace.rect.left,
                (view.y - itemSpace.rect.top).toInt() + itemSpace.topDrawableMargin.top,
                right - itemSpace.topDrawableMargin.right - itemSpace.rect.right,
                view.y.toInt() - itemSpace.topDrawableMargin.bottom
            )
            itemSpace?.topDrawable?.draw(c)
            // 绘制下间隔填充物
            itemSpace?.bottomDrawable?.setBounds(
                left + itemSpace.bottomDrawableMargin.left  + itemSpace.rect.left,
                (view.y + view.height).toInt() + itemSpace.bottomDrawableMargin.top,
                right - itemSpace.bottomDrawableMargin.right - itemSpace.rect.right,
                (view.y + view.height).toInt() + itemSpace.rect.bottom - itemSpace.bottomDrawableMargin.bottom
            )
            itemSpace?.bottomDrawable?.draw(c)
        }

    }

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        super.getItemOffsets(outRect, view, parent, state)
        val viewHolder = parent.getChildViewHolder(view)
        val itemSpace = spaceArray[viewHolder.itemViewType]
        itemSpace?.rect?.apply {
            outRect.top = top
            outRect.bottom = bottom
            outRect.left = left
            outRect.right = right
        }
    }

}

你可能感兴趣的:(RecycleView ItemDecoration 自定义绘制)