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>


 

 

 

 

 

發佈了48 篇原創文章 · 獲贊 9 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章