RecyclerView的萬能分割線
阿新 • • 發佈:2018-12-20
//新增自定義分割線 RecyclerViewDivider divider = new RecyclerViewDivider (); divider.setMargin(getActivity(), 72, 0 , 0, 0); recyclerView.addItemDecoration(divider); import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.LinearLayout; /** * @author fz * @date 2018/11/8 * describe: */ public class RecyclerViewDivider extends RecyclerView.ItemDecoration { private Drawable mDivider; private int mDividerHeight = 1;//px private Paint mPaint; private Paint mMarginPaint; private int mOrientation; private final Rect mBounds = new Rect(); private Rect mMarginBounds; private int mMarginColor = 0XFFFFFFFF; private int mDividerColor = 0XFFE2E2E2; public RecyclerViewDivider() { mOrientation = LinearLayout.VERTICAL; } public RecyclerViewDivider(boolean isVertical) { if (isVertical) { mOrientation = LinearLayout.VERTICAL; } else { mOrientation = LinearLayout.HORIZONTAL; } } public void setDividerHeight(int px) { this.mDividerHeight = px; } public void setDividerHeight(Context c, int dp) { this.mDividerHeight = (int) (dp * c.getResources().getDisplayMetrics().density); } public void setDrawable(@NonNull Drawable drawable) { mDivider = drawable; } public void setColor(int color) { mPaint = new Paint(); mPaint.setColor(color); } public void setColor(Context c, @ColorRes int colorId) { setColor(ContextCompat.getColor(c, colorId)); } public void setMarginColor(int color) { mMarginPaint = new Paint(); mMarginPaint.setColor(color); } public void setMarginColor(Context c, @ColorRes int colorId) { setMarginColor(ContextCompat.getColor(c, colorId)); } public void setMargin(int left, int top, int right, int bottom) { mMarginBounds = new Rect(); mMarginBounds.left = left; mMarginBounds.top = top; mMarginBounds.right = right; mMarginBounds.bottom = bottom; } public void setMargin(Context c, int leftDp, int topDp, int rightDp, int bottomDp) { float density = c.getResources().getDisplayMetrics().density; mMarginBounds = new Rect(); mMarginBounds.left = (int) (leftDp * density); mMarginBounds.top = (int) (topDp * density); mMarginBounds.right = (int) (rightDp * density); mMarginBounds.bottom = (int) (bottomDp * density); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { if (parent.getLayoutManager() == null) { return; } if (mOrientation == LinearLayout.VERTICAL) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } /** * 繪製縱向列表時的分隔線 這時分隔線是橫著的 * 每次 left相同,top根據child變化,right相同,bottom也變化 * * @param canvas * @param parent */ @SuppressLint("NewApi") private void drawVertical(Canvas canvas, RecyclerView parent) { canvas.save(); final int left; final int right; if (parent.getClipToPadding()) { left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom()); } else { left = 0; right = parent.getWidth(); } final int childCount = parent.getChildCount(); for (int i = 0; i < childCount - 1; i++) { final View child = parent.getChildAt(i); parent.getDecoratedBoundsWithMargins(child, mBounds); final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child)); int top = bottom - mDividerHeight; //根據drawable來繪製分割線 if (null != mDivider) { int sicWidth = mDivider.getIntrinsicWidth(); if (sicWidth > 0) { top = bottom - sicWidth; } if (null != mMarginBounds) { mDivider.setBounds(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom); } else { mDivider.setBounds(left, top, right, bottom); } mDivider.draw(canvas); continue; } if (null == mPaint) { mPaint = new Paint(); mPaint.setColor(mDividerColor); } //繪製普通分割線 if (null == mMarginBounds) { canvas.drawRect(left, top, right, bottom, mPaint); continue; } //繪製含間距分割線 if (null == mMarginPaint) { mMarginPaint = new Paint(); mMarginPaint.setColor(mMarginColor); } if (mMarginBounds.left > 0) { canvas.drawRect(0, top + mMarginBounds.top, mMarginBounds.left, bottom - mMarginBounds.bottom, mMarginPaint); } if (mMarginBounds.right > 0) { canvas.drawRect(right - mMarginBounds.right, top + mMarginBounds.top, mMarginBounds.right, bottom - mMarginBounds.bottom, mMarginPaint); } canvas.drawRect(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom, mPaint); } canvas.restore(); } /** * 繪製橫向列表時的分隔線 這時分隔線是豎著的 * l、r 變化; t、b 不變 * * @param canvas * @param parent */ private void drawHorizontal(Canvas canvas, RecyclerView parent) { canvas.save(); final int top; final int bottom; if (parent.getClipToPadding()) { top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); canvas.clipRect(parent.getPaddingLeft(), top, parent.getWidth() - parent.getPaddingRight(), bottom); } else { top = 0; bottom = parent.getHeight(); } final int childCount = parent.getChildCount(); for (int i = 0; i < childCount - 1; i++) { final View child = parent.getChildAt(i); parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds); int right = mBounds.right + Math.round(ViewCompat.getTranslationX(child)); int left = right - mDividerHeight; //根據drawable來繪製分割線 if (null != mDivider) { int sicWidth = mDivider.getIntrinsicWidth(); if (sicWidth > 0) { left = right - sicWidth; } if (null != mMarginBounds) { mDivider.setBounds(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom); } else { mDivider.setBounds(left, top, right, bottom); } mDivider.draw(canvas); continue; } if (null == mPaint) { mPaint = new Paint(); mPaint.setColor(mDividerColor); } //繪製普通分割線 if (null == mMarginBounds){ canvas.drawRect(left, top, right, bottom, mPaint); continue; } //繪製含間距分割線 if (null == mMarginPaint) { mMarginPaint = new Paint(); mMarginPaint.setColor(mMarginColor); } if (mMarginBounds.top > 0){ canvas.drawRect(left + mMarginBounds.left, 0, right - mMarginBounds.right, mMarginBounds.top, mMarginPaint); } if (mMarginBounds.bottom > 0){ canvas.drawRect(left + mMarginBounds.left, bottom - mMarginBounds.bottom, right - mMarginBounds.right, bottom, mPaint); } canvas.drawRect(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom, mPaint); } canvas.restore(); } //獲取分割線尺寸 @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (mOrientation == LinearLayout.VERTICAL) { if (0 == mDividerHeight && null != mDivider) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, 0, mDividerHeight); } } else { if (0 == mDividerHeight && null != mDivider) { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } else { outRect.set(0, 0, mDividerHeight, 0); } } } }