RecyclerView——ItemDecoration笔记

来源:互联网 发布:smali文件转java 编辑:程序博客网 时间:2024/06/05 22:52

之前项目中看到了系统工程中有的模块RecyclerView里面的Item分割线,竟然使用的是一个View,于是我随手改了一下,在这里顺便复习一下相关的知识。

首先呢需要继承RecyclerView.ItemDecoration然后重写下面的方法

Public Methods void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) 获取项的偏移量(指定outRect指定中的 top、left、right、bottom 就可以控制各个方向的间隔) void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) 绘制组件的UI效果(所有decoration都在item绘制之前绘制,在 ItemView 内容之下绘制图形 ) void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) decoration在view之后绘制(在 ItemView 内容之上绘制图形)

下面我主要去讨论onDraw中去画普通的分割线
1. LinearLayoutManager中设置分割线(VERTICAL)

@Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);        outRect.bottom = 10;    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        int childCount = parent.getChildCount();        int left = parent.getPaddingLeft();        int right = parent.getWidth() - parent.getPaddingRight();        for (int i = 0; i < childCount; i++) {            View childAt = parent.getChildAt(i);            float top = childAt.getBottom();            float bottom = childAt.getBottom() + 10;            Shader shader = new LinearGradient(                    left, right, bottom, bottom, Color.parseColor("#FFBBFF"),                    Color.parseColor("#EBEBEB"), Shader.TileMode.MIRROR);            mPaint.setShader(shader);            c.drawRect(left, top, right, bottom, mPaint);        }    }

实现的效果如下:

这里写图片描述

  1. LinearLayoutManager中设置分割线(HORIZONTAL)
@Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);        outRect.right = 10;    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            View childAt = parent.getChildAt(i);            int left = childAt.getRight();            int right = childAt.getRight() + 10;            float top = childAt.getTop();            int bottom = childAt.getHeight() - childAt.getTop();            c.drawRect(left, top, right, bottom, mPaint);        }    }

效果如下:

这里写图片描述
3.用户在设置了GridLayoutManager的情况下设置分割线:

@Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);        int position = parent.getChildAdapterPosition(view);        if (isLastColumn(position, parent)) {            right = 0;        }        if (isLastRow(parent)) {            bottom = 0;        }        outRect.set(0, 0, right, bottom);    } /*判断是不是最后一行*/    private boolean isLastRow(RecyclerView parent) {        GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();        int spanCount = layoutManager.getSpanCount();        int itemCount = parent.getAdapter().getItemCount();        int lastRawCount = itemCount % spanCount;        if (lastRawCount == 0 || lastRawCount < spanCount) {            return true;        }        return false;    /*判断是不是最后一列*/    private boolean isLastColumn(int position, RecyclerView parent) {        GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();        int spanCount = layoutManager.getSpanCount();        //如果是最后一列的话,那么余数为0        if ((position + 1) % spanCount == 0) {            return true;        }        return false;    }

因为我们在给网格划线的时候,不想画出屏幕边缘左右两条线,所以进行了判断。
接着我们就要重写onDraw方法,画网格需要画两条线,也很简单,直接看代码

    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        drawHorizontal(c, parent);        drawVertical(c, parent);    }    private void drawVertical(Canvas c, RecyclerView parent) {        int count = parent.getChildCount();        for (int i = 0; i < count; i++) {            View childView = parent.getChildAt(i);            //这样左边就不会也画线了,如果需要左侧划线那么设置childView.getLeft();            int left = childView.getRight();            int right = left + 10;            int top = childView.getTop();            int bottom = childView.getBottom() + 10;            c.drawRect(left, top, right, bottom, mPaint);        }    }    private void drawHorizontal(Canvas c, RecyclerView parent) {        int count = parent.getChildCount();        for (int i = 0; i < count; i++) {            View childView = parent.getChildAt(i);            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) childView.getLayoutParams();            int left = childView.getLeft() - params.leftMargin;            int right = childView.getRight() + params.rightMargin;            int top = childView.getBottom() + params.bottomMargin;            int bottom = top + 10;            c.drawRect(left, top, right, bottom, mPaint);        }    }

效果图如下:

这里写图片描述

Google官方也提供了设置分割线的方法:
recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));

上面很多的篇幅,都用来介绍了onDraw的方法,后面还有一个方法是onDrawOver,这个方法也很神奇。因为在这个
方法中通过Canvas可以直接把一些图片或者其他数据直接绘制在Item上,所以这个方法可以实现一些商品的排行榜什么的。
具体的使用方法,以及实现的炫酷效果可以在网上搜索。