萬能的給 RecyclerView新增邊框線 和 圖片邊框線
阿新 • • 發佈:2019-01-06
/** * Created by 寶寶 on 2017/12/8. */ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; importandroid.support.v7.widget.RecyclerView; import android.view.View; /** * @DateTime: 2016-07-21 17:55 * @Author: duke * @Deacription: recyclerview萬能分割線 */ public class RecycleViewDivider extends RecyclerView.ItemDecoration { private Paint mPaint;//如果需要用畫筆手繪 private Drawable mDrawableDivider;//如果需要繪製給定的drawableprivate int mPaintDividerLength = 2;//分割線寬度或高度 private DrawType drawType;//用畫筆繪製顏色,還是繪製特定的drawable /** * 注意:列表的方向 * LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL */ private int mOrientation; //系統預設的分割線 private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; /** * 自定義分割線 * * @param context * @param orientation 列表方向 * @param drawableId 分割線圖片 */ public RecycleViewDivider(Context context, int orientation, int drawableId) { if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { throw new IllegalArgumentException("請輸入正確的引數!"); } mOrientation = orientation; if (drawableId == -100) { //獲取系統的樣式 final TypedArray a = context.obtainStyledAttributes(ATTRS); mDrawableDivider = a.getDrawable(0); a.recycle(); } else { mDrawableDivider = ContextCompat.getDrawable(context, drawableId); } //表明繪製drawable drawType = DrawType.USEDRAWABLE; } /** * @param context 上下文 * @param orientation 列表方向 */ public RecycleViewDivider(Context context, int orientation) { this(context, orientation, -100); } /** * 自定義分割線 * @param orientation 列表方向 * @param dividerHeight 分割線高度 * @param dividerColor 分割線顏色 */ public RecycleViewDivider(int orientation, int dividerHeight, int dividerColor) { if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { throw new IllegalArgumentException("請輸入正確的引數!"); } mOrientation = orientation; if (dividerHeight != -100) { //分割線高度 mPaintDividerLength = dividerHeight; } //建立特定畫筆 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(dividerColor); mPaint.setStyle(Paint.Style.FILL); //表明繪製用paint drawType = DrawType.USEPAINT; } /** * 自定義分割線 * * @param orientation 列表方向 * @param dividerColor 分割線顏色 */ public RecycleViewDivider(int orientation, int dividerColor) { this(orientation, -100, dividerColor); } /** * 看圖說話:get Item Offsets,獲得item的偏移量。此方法用來控制item的偏移 * @param outRect * @param view * @param parent * @param state */ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); /** * 列表的方向為橫向,畫分割線就是縱向的,需要確定的是child的右邊偏移值 * 留出空間畫分割線 */ if (this.mOrientation == LinearLayoutManager.HORIZONTAL) switch (drawType) { case USEPAINT: outRect.set(0, 0, mPaintDividerLength, 0); break; case USEDRAWABLE: outRect.set(0, 0, mDrawableDivider.getIntrinsicWidth(), 0); break; } /** * 列表的方向為縱向,畫分割線就是橫向的,需要確定的是child的下邊偏移值 * 留出空間畫分割線 */ else if (this.mOrientation == LinearLayoutManager.VERTICAL) switch (drawType) { case USEPAINT: outRect.set(0, 0, 0, mPaintDividerLength); break; case USEDRAWABLE: outRect.set(0, 0, 0, mDrawableDivider.getIntrinsicHeight()); break; } } /** * 繪製分割線 * @param c * @param parent * @param state */ @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); if (mOrientation == LinearLayoutManager.VERTICAL) { //列表是縱向的,需要繪製橫向的分割線 drawHorizontal(c, parent); } else { //列表是橫向的,需要繪製縱向的分割線 drawVertical(c, parent); } } /** * 繪製橫向 item 分割線。左、上、右都是可計算的,下需要獲取給定的高度值 * @param canvas * @param parent */ private void drawHorizontal(Canvas canvas, RecyclerView parent) { //左邊:到父容器的left內間距位置值 final int left = parent.getPaddingLeft(); //右邊:到父容器的right內間距位置值 final int right = parent.getMeasuredWidth() - parent.getPaddingRight(); final int childSize = parent.getChildCount(); //迴圈繪製每條分割線 for (int i = 0; i < childSize; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); //上邊:具體的某條分割線的左邊以child的(bottom+bottomMargin)位置值 final int top = child.getBottom() + layoutParams.bottomMargin; //下邊:根據型別判斷 int bottom; switch (drawType){ case USEPAINT://構造方法宣告使用畫筆繪製 //下邊:top加上指定的高度 bottom = top + mPaintDividerLength; if (mPaint != null) { canvas.drawRect(left, top, right, bottom, mPaint); } break; case USEDRAWABLE://構造方法宣告使用drawable if (mDrawableDivider != null) { //下邊:top加上指定的高度 bottom = top + mDrawableDivider.getIntrinsicHeight(); mDrawableDivider.setBounds(left, top, right, bottom); mDrawableDivider.draw(canvas); } break; } } } /** * 繪製縱向 item 分割線。上、下、左都是可計算的,右側需要獲取給定的寬度值 * @param canvas * @param parent */ private void drawVertical(Canvas canvas, RecyclerView parent) { //上邊:到父容器的top內間距位置值 final int top = parent.getPaddingTop(); //下邊:到父容器的bottom內間距位置值 final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom(); final int childSize = parent.getChildCount(); //迴圈繪製每條分割線 for (int i = 0; i < childSize; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); //左邊:具體的某條分割線的左邊以child的(right+rightMargin)位置值 final int left = child.getRight() + layoutParams.rightMargin; //右邊:根據型別判斷 int right; switch (drawType){ case USEPAINT://構造方法宣告使用畫筆繪製 //右邊:left加上指定的寬度 right = left + mPaintDividerLength; if (mPaint != null) { canvas.drawRect(left, top, right, bottom, mPaint); } break; case USEDRAWABLE://構造方法宣告使用drawable if (mDrawableDivider != null) { //右邊:left加上指定的寬度 right = left + mDrawableDivider.getIntrinsicWidth(); mDrawableDivider.setBounds(left, top, right, bottom); mDrawableDivider.draw(canvas); } break; } } } public static enum DrawType { USEPAINT(1),//用畫筆畫 USEDRAWABLE(2); //畫特定的drawable private final int type; DrawType(int type) { this.type = type; } public int getType() { return type; } } }