Android - How to add a dashed / dashed line dividing line for RecyclerView?

I used the code from this answer to create a solid dividing line for my RecyclerView s.

However, I would like the string to be dotted / dotted.

I already have the line_dashed.xml resource that I use elsewhere in my application:

 <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line" > <stroke android:color="@color/blue" android:dashGap="12dp" android:dashWidth="12dp" android:width="1dp" /> </shape> 

But if I try to apply this as a resource, which can be obtained through my call to recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getContext())) , not a single line will be drawn at all.

How to resolve so dashed line?

+5
source share
2 answers

Just add your resource to this decorator.

 DividerItemDecoration decorator = new DividerItemDecoration(ContextCompat.getDrawable(getContext(), R.drawable.line_dashed)); recyclerView.addItemDecoration(decorator); 

and class DividerItemDecorator:

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; private int mPaddingLeft; public DividerItemDecoration(Drawable divider) { mDivider = divider; mPaddingLeft = 0; } public DividerItemDecoration(Drawable divider, int paddingLeft) { mDivider = divider; mPaddingLeft = paddingLeft; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (mDivider == null) return; if (parent.getChildAdapterPosition(view) < 1) return; if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { outRect.top = mDivider.getIntrinsicHeight(); } else { outRect.left = mDivider.getIntrinsicWidth(); } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { if (mDivider == null) { super.onDrawOver(c, parent, state); return; } if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { final int left = parent.getPaddingLeft() + mPaddingLeft; final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 1; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int size = mDivider.getIntrinsicHeight(); final int top = child.getTop() - params.topMargin; final int bottom = top + size; mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } else { //horizontal final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 1; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int size = mDivider.getIntrinsicWidth(); final int left = child.getLeft() - params.leftMargin; final int right = left + size; mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } } private int getOrientation(RecyclerView parent) { if (parent.getLayoutManager() instanceof LinearLayoutManager) { LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); return layoutManager.getOrientation(); } else throw new IllegalStateException("DividerItemDecoration can only be used with a LinearLayoutManager."); } } 

Should work, I tested it.

UPDATE:

  android:layerType="software" 

add this parameter to xml for recyclerView Also add size to your form:

 <size android:height="1dp"/> 
+5
source

Drawing a dashed line in Android is not so simple. Drowable, as you have shown, and even just drawing a dotted line on canwas ( canvas.drawLine(..., paintWithDashEffect) ) does not always work (not for all devices). You can use android:layerType="software" or draw a path. IMHO, the best solution is not to draw a dashed line at all (draw only a line). But if you really need a dashed line, you can use @fearless's answer or something like this:

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { private Paint mPaint; private int mDividerSize; public DividerItemDecoration(int dividerSize) { mDividerSize = dividerSize; mPaint = new Paint(); mPaint.setColor(ContextCompat.getColor(context, R.color.colorAccent)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(dividerSize); mPaint.setPathEffect(new DashPathEffect(new float[]{dashGap,dashWidth},0)); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.bottom = mDividerSize; } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); Path path = new Path(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin + mDividerSize/2; path.moveTo(left, top); path.lineTo(right, top); } c.drawPath(path, mPaint); } } 
0
source

All Articles