实现RecyclerView局部背景

image.png

实现以上页面效果,很多开发者会用NestedScrollView去做,然后用recyclerview实现中间菜单区域,在给recyclerview整体做一个带圆角的白色背景图。但是如果整体页面用RecyclerView实现,layoutManager用GribLayoutManager(3),那如何解决以下问题呢?

1.顶部用户信息区域与banner区域做一个整体背景图
2.中间菜单区域使用白色圆角背景图呢
3.菜单区域的最左,最右的菜单按钮,其对应leftmargin与rightmargin不一致

为了解决以上问题,我们得要使用ItemDecoration类,google对于它的解释如下

An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter's data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.

解释如下:

ItemDecoration允许应用从适配器的数据向特定的多个Item视图,添加特殊的图形和布局偏移。 这对于在项目,突出显示,可视分组边界等之间绘制分隔线很有用。

public abstract static class ItemDecoration {
    // 在条目绘制之前绘制装饰,即在RecyclerView条目的底层展示。
    public void onDraw(Canvas c, RecyclerView parent, State state) {
    }
    // 在条目绘制之后绘制装饰,即在RecyclerView条目的上层展示。
    public void onDrawOver(Canvas c, RecyclerView parent, State state) {
    }
    // 重新设置条目的边距
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
    }
}

基于ui效果,我们只用在ondraw方法进行操作即可

class BackgroundItemDecoration : RecyclerView.ItemDecoration() {
    private val mTempRect = Rect()
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        val childCount = parent.childCount
        var left = -1
        var top = -1
        var right = -1
        var bottom = -1
        for (i in 0 until childCount) {
            val view = parent.getChildAt(i)
            if (view.visibility != View.GONE && isTargetItem(view, parent)) {
                parent.getDecoratedBoundsWithMargins(view, mTempRect)
                if(left == -1){
                    left = mTempRect.left
                    top = mTempRect.top
                }else if(isRightItem(view,parent)){
                    right = mTempRect.right
                }else{
                    bottom = mTempRect.bottom
                }
            }
        }
        val drawable =  ContextCompat.getDrawable(parent.context,R.drawable.shape_round_10_white_bg)
        drawable?.setBounds(left,top,right,bottom)
        drawable?.draw(c)
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        super.getItemOffsets(outRect, view, parent, state)

    }

    private fun isTargetItem(view: View, parent: RecyclerView): Boolean {
        var target = false
        if (view.visibility != View.GONE) {
            val adapter = parent.adapter
            if (adapter != null && adapter.getItemViewType(parent.getChildAdapterPosition(view))
                    != BaseQuickAdapter.HEADER_VIEW && adapter.getItemViewType(parent.getChildAdapterPosition(view))
                    != BaseQuickAdapter.FOOTER_VIEW) {
                target = true
            }
        }
        return target
    }

    private fun isRightItem(view: View, parent: RecyclerView): Boolean {
        val isLeft: Boolean
        val layoutManager = parent.layoutManager
        isLeft = if (layoutManager !is GridLayoutManager) {
            true
        } else {
            val spanIndex: Int = layoutManager.spanSizeLookup
                    .getSpanIndex(parent.getChildAdapterPosition(view),
                            layoutManager.spanCount)
            spanIndex == 2
        }
        return isLeft
    }
}
image.png

不知道大家对以上的ui该如何代码实现布局呢?

你可能感兴趣的:(实现RecyclerView局部背景)