How to make a rounded dashes or dots for line drawable shape
Asked Answered
L

2

5

Is there a way that can I make the cap/dot rounded, like in the attached picture?

enter image description here

<shape
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="line">

    <stroke 
    android:width="2dp"
    android:color="@color/grey"
    android:dashWidth="3dp"
    android:dashGap="3dp" />

</shape>

NOTE

Guys, I know how to make a dotted line, I'm asking how to make a "rounded" dashes.!! look at this picture from Adobe XD to know what I mean..!

enter image description here

Lisabeth answered 1/10, 2019 at 6:14 Comment(3)
There is not proper way to make dashed line as rounded in Android. Can you tell where exactly you need to use so I can suggest other way.Hickory
@NiranjPatel I just want a line as separate between two views.!Lisabeth
Create image like this and apply on view.Hickory
H
5

You can achieve a goal using a custom view and drawing on canvas. Please, try this and adjust sizes/styling for your needs:

public class RoundedDashView extends View {

public enum Orientation {
    VERTICAL,
    HORIZONTAL
}

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path path = new Path();
private Orientation orientation = Orientation.HORIZONTAL;

public RoundedDashView(Context context) {
    super(context);
    init();
}

public RoundedDashView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init();
}

public RoundedDashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

public RoundedDashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init();
}

private void init() {
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(10);
    paint.setColor(Color.GRAY);
    paint.setPathEffect(new DashPathEffect(new float[]{20, 25}, 20));
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    path.reset();
    if (orientation == Orientation.VERTICAL) {
        path.moveTo(getWidth() / 2, 0);
        path.quadTo(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight());
    } else {
        path.moveTo(0, getHeight() / 2);
        path.quadTo(getWidth() / 2, getHeight() / 2, getWidth(), getHeight() / 2);
    }
    canvas.drawPath(path, paint);
}

public void setOrientation(Orientation orientation) {
    this.orientation = orientation;
    invalidate();
}
}
Haha answered 1/10, 2019 at 7:25 Comment(3)
perfect, but how can I make the line vertical from code.!? I've tried to add a 90 rotation from xml, but it adds a big top and bottom padding.!!Lisabeth
Do you need this only in a vertical orientation? Or it should be configurable (vertical/horizontal)?Haha
it would be a lot better if it was configurableLisabeth
U
3

I used the answer above and modified it to make it configurable in the xml. Copy the java class:

public class RoundedDashView extends View {

private static final int HORIZONTAL = 0;
private static final int VERTICAL = 1;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path path = new Path();

private float gap = 6f;
private float width = 8f;
private int orientation = HORIZONTAL;
private int color = getResources().getColor(R.color.dot_inactive);

public RoundedDashView(Context context) {
    super(context);
    init();
}

public RoundedDashView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public RoundedDashView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedDashView, defStyleAttr, R.style.RoundedDasViewDefault);
    orientation = a.getInt(R.styleable.RoundedDashView_orientation, VERTICAL);
    color = a.getColor(R.styleable.RoundedDashView_dividerDashColor, color);
    gap = a.getFloat(R.styleable.RoundedDashView_dividerDashGap, gap);
    width = a.getFloat(R.styleable.RoundedDashView_dividerDashWidth, width);

    init();
    a.recycle();
}

public void init() {
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(gap);
    paint.setColor(color);
    paint.setPathEffect(new DashPathEffect(new float[]{gap, width}, gap));
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    path.reset();
    applyOrientation();
    canvas.drawPath(path, paint);
}

public void setOrientation(int orientation) {
    this.orientation = orientation;
    applyOrientation();
    invalidate();
}

public void applyOrientation() {
    if (orientation == VERTICAL) {
        path.moveTo((float) getWidth() / 2, 0);
        path.quadTo((float) getWidth() / 2, (float) getHeight() / 2, (float) getWidth() / 2, getHeight());
    } else if (orientation == HORIZONTAL) {
        path.moveTo(0, (float) getHeight() / 2);
        path.quadTo((float) getWidth() / 2, (float) getHeight() / 2, getWidth(), (float) getHeight() / 2);
    }
}

public void setColor(int color) {
    this.color = color;
    paint.setColor(color);
    invalidate();
}

public int getColor() {
    return color;
}
}

Create an attr file in the /res directory and add this

<declare-styleable name="RoundedDashView">
    <attr name="dividerDashGap" format="float" />
    <attr name="dividerDashWidth" format="float" />
    <attr name="dividerDashColor" format="reference|color" />
    <attr name="orientation" format="enum">
        <enum name="vertical" value="1" />
        <enum name="horizontal" value="0" />
    </attr>
</declare-styleable>

Add a style to the styles file

<style name="RoundedDasViewDefault">
    <item name="dividerDashGap">6</item>
    <item name="dividerDashWidth">8</item>
    <item name="dividerDashColor">@color/dot_inactive</item>
    <item name="orientation">horizontal</item>
</style>

Set attributes in XML

<com.neon.robinfood.utils.RoundedDashView
   android:layout_width="6dp"
   android:layout_marginStart="8dp"
   android:layout_height="@dimen/dimen_36dp"
   app:dividerDashGap="6"
   app:dividerDashWidth="8"
   app:dividerDashColor="@color/red"
   app:orientation="vertical"/>
Uzbek answered 30/4, 2021 at 5:40 Comment(1)
you deserve more upvotes. thanks a lot!Leipzig

© 2022 - 2024 — McMap. All rights reserved.