RecyclerView 实现 间隔线

一、先看效果:

   

二、简述实现方法

      1、 给RecyclerView添加ItemDecoration(recyclerView.addItemDecoration(new DividerItemDecoration(this));)

       2、实现ItemDecoration (在getItemOffsets 指定要绘制分割线的偏移量,onDraw 绘制自己的间隔线)

       3、如果用系统的什么东不用做,如果用自己的替换主题属性listDivider(<item name="android:listDivider">@drawable/shape_item_divider</item>)

三、实现代码

DividerItemDecoration.java

   public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private int mOrientation = -1;
    private Drawable mDivider;
    //给分割线加距离左右的边距
    private int paddingLeft = 0, paddingRight = 0;
    private int[] attrs = new int[]{
            android.R.attr.listDivider
    };


    public DividerItemDecoration(Context context, int orientation) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs);
        mDivider = typedArray.getDrawable(0);
        typedArray.recycle();
        setOrientation(orientation);
    }

    public DividerItemDecoration(Context context) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs);
        mDivider = typedArray.getDrawable(0);
        typedArray.recycle();
    }

    public void setOrientation(int mOrientation) {
        if (mOrientation != LinearLayoutManager.HORIZONTAL && mOrientation != LinearLayoutManager.VERTICAL) {
            throw new IllegalArgumentException("嗨,给个布局吧");
        }
        this.mOrientation = mOrientation;
    }

    public void setPaddingLR(int left, int right) {
        this.paddingLeft = left;
        this.paddingRight = right;
    }


    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
//  2、调用这个绘制方法  RecyclerView会毁掉该绘制方法,需要你自己去绘制条目的间隔线
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            //垂直
            drawVertical(c, parent);
        } else if (mOrientation == LinearLayoutManager.HORIZONTAL) {
            // 水平
            drawHorizontal(c, parent);
        } else {
            drawHorizontal2(c, parent);
            drawVertical2(c, parent);
        }
    }

    private void drawHorizontal2(Canvas canvas, RecyclerView parent) {
        //绘制水平间隔线
        int childcount = parent.getChildCount();
        for (int i = 0; i < childcount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int left = child.getLeft() - params.leftMargin;
            int right = child.getRight() + params.rightMargin;
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
    }

    private void drawVertical2(Canvas canvas, RecyclerView parent) {
        //绘制垂直间隔线
        int childcount = parent.getChildCount();
        for (int i = 0; i < childcount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int left = child.getRight() + params.rightMargin;
            int right = left + mDivider.getIntrinsicWidth();
            int top = child.getTop() - params.topMargin;
            int bottom = child.getBottom() + params.bottomMargin;
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }

    }

    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        int top = parent.getPaddingTop();
        int bottom = parent.getHeight() - parent.getPaddingBottom();
        for (int i = 0; i < parent.getChildCount(); i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            //params.bottomMargin上一个的item的margin
            //(int)ViewCompat.getTranslationY(child) 动画移动的y值
            int left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));// 得到当前这个控件距离父容器的高度
            int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }

    }

    private void drawVertical(Canvas canvas, RecyclerView parent) {
        int left = parent.getPaddingLeft() + paddingLeft;
        int right = parent.getWidth() - parent.getPaddingRight() - paddingRight;
        for (int i = 0; i < parent.getChildCount(); i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            //params.bottomMargin上一个的item的margin
            //(int)ViewCompat.getTranslationY(child) 动画移动的y值
            int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));// 得到当前这个控件距离父容器的高度
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }

    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        //1、调用此方法,获取条目的偏移量
        //获取条目的偏移量(所有的条目都回调用一次该方法)
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            int position = parent.getLayoutManager().getPosition(view);
            Log.i("wxf", "itemCont:" + parent.getLayoutManager().getItemCount());
            Log.i("wxf", "position:" + position);
            //如果当前的position是最后一个,就不画
            if (position != parent.getLayoutManager().getItemCount() - 1) {
                //垂直
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            }
        } else if (mOrientation == LinearLayoutManager.HORIZONTAL) {
            // 水平
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        } else {
            //四个方向的偏移值
            int right = mDivider.getIntrinsicWidth();
            int bottom = mDivider.getIntrinsicHeight();

            if (isLastColum(view, parent)) {
                //最后一列
                right = 0;
            }
            if (isLastRow(parent)) {
                //最后一行
                bottom = 0;
            }
            outRect.set(0, 0, right, bottom);

        }
    }

    private boolean isLastColum(View view, RecyclerView parent) {

        if (parent.getLayoutManager() instanceof GridLayoutManager) {
            GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
            int itemPosition = layoutManager.getPosition(view);
            //列
            int spanCount = layoutManager.getSpanCount();
            if ((itemPosition + 1) % spanCount == 0) {
                return true;
            }
        }
        return false;
    }

    private boolean isLastRow(RecyclerView parent) {

        if (parent.getLayoutManager() instanceof GridLayoutManager) {
            GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
            //int itemPosition = layoutManager.getPosition(view);
            //列
            int spanCount = layoutManager.getSpanCount();
            int childCount = parent.getAdapter().getItemCount();
            //最后一行的数量小于spanCount
            int lastRowCount = childCount % spanCount;
            if (lastRowCount == 0 || lastRowCount < spanCount) {
                return true;
            }
        }
        return false;
    }
}

 

shape_item_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:width="2dp" android:height="2dp"/>
    <solid android:color="#ff0000"/>
</shape>


 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值