RecyclerView.ItemDecoration

weixin_34290000發表於2016-08-15
public class DividerLinearItemDecoration extends RecyclerView.ItemDecoration {   
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;   
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;   
private int dividerSpace;//分割條寬度
private ColorDrawable mDivider;//分割條顏色
private int mOrientation;

public DividerLinearItemDecoration(Context context, int orientation) {        
dividerSpace = dip2px(context, 1);
mDivider = new ColorDrawable(Color.TRANSPARENT);
setOrientation(orientation);
}

public void setDividerSpace(int dividerSpace) {
    this.dividerSpace = dividerSpace;
}

public void setOrientation(int orientation) {
    if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {            
throw new IllegalArgumentException("invalid orientation");
    }
    mOrientation = orientation;
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (mOrientation == VERTICAL_LIST) {
        drawVertical(c, parent);
    } else {
        drawHorizontal(c, parent);
    }
}

/**
 * 建立的範圍:
 * (1)垂直的時候
 * 左邊=RecyclerView的左邊-paddingLeft
 * 右邊=RecyclerView的右邊-paddingRight
 * 為啥這麼做呢?
 * 因為mDivider是繪製的item view的最低層,在垂直方向,item view的間隔是上下的,
 * mDivider的範圍就超出前面顯示的內容,即左右突出了
 * 頂邊=
 **/
public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();
    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int top = child.getBottom() + params.bottomMargin + 
               Math.round(ViewCompat.getTranslationY(child));
        final int bottom = top + dividerSpace;            
        mDivider.setBounds(left, top, right, bottom); 
       mDivider.draw(c);
    }
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
    final int top = parent.getPaddingTop();
    final int bottom = parent.getHeight() - parent.getPaddingBottom();
    final int childCount = parent.getChildCount(); 
   for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int left = child.getRight() + params.rightMargin +
                Math.round(ViewCompat.getTranslationX(child));
        final int right = left + dividerSpace;
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}
/** 
* 這個方法比onDraw()先執行
 * 這裡的作用是設定Rect的範圍,
 * RecyclerView會呼叫這個方法來設定每個item view的padding值
 * Rect對應item view:
 * left=paddingLeft
 * right=paddingLeft
 * top=paddingTop 
* bottom=paddingBottom
 **/

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    int position = parent.getChildAdapterPosition(view);
    //垂直方向
    if (mOrientation == VERTICAL_LIST) {
        outRect.set(0, 0, 0, dividerSpace);//垂直滾動則設定paddingBottom的值
        return;
    }
    //水平方向
    if (position == parent.getChildCount()) {
        outRect.set(0, 0, 0, 0);//最後一個item,尾部不需要間隔
    } else {
        outRect.set(0, 0, dividerSpace, 0);//水平滾動則設定paddingRight的值   
 }
}

public static int dip2px(Context context, float dipValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dipValue * scale + 0.5f);
}}