How do I make a dotted/dashed line in Android?

Android

Android Problem Overview


I'm trying to make a dotted line. I'm using this right now for a solid line:

LinearLayout divider = new LinearLayout( this );
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, 2 );
divider.setLayoutParams( params );
divider.setBackgroundColor( getResources().getColor( R.color.grey ) );

I need something like this, but dotted instead of solid. I'd like to avoid making hundreds of layouts alternating between a transparent layout and solid layout.

Android Solutions


Solution 1 - Android

Without java code:

drawable/dotted.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">

    <stroke
       android:color="#FF00FF"
       android:dashWidth="10px"
       android:dashGap="10px"
       android:width="1dp"/>
</shape>

view.xml:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="5dp"
    android:src="@drawable/dotted"
    android:layerType="software" />

Effect: enter image description here

Solution 2 - Android

the path effect is set on the paint object

Paint fgPaintSel = new Paint();
fgPaintSel.setARGB(255, 0, 0,0);
fgPaintSel.setStyle(Style.STROKE);
fgPaintSel.setPathEffect(new DashPathEffect(new float[] {10f,20f}, 0f));

you can create all sorts of dotted patterns by supplying more numbers in the int[] array it specifies the ratios of dash and gap. This is a simple, equally dashed, line.

Solution 3 - Android

Creating dotted line using XML.
Create xml in drawable folder and give that background to the item to which you want to set dotted border.

Creating XML Background "dashed_border":

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape>
            <solid android:color="#ffffff" />
            <stroke
                android:dashGap="5dp"
                android:dashWidth="5dp"
                android:width="1dp"
                android:color="#0000FF" />
            <padding
                android:bottom="5dp"
                android:left="5dp"
                android:right="5dp"
                android:top="5dp" />
        </shape>
    </item>
</layer-list>

Adding that background to item:

<Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/dashed_border"/>

Solution 4 - Android

Create xml (view_line_dotted.xml):

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:bottom="-1dp"
            android:left="-1dp"
            android:right="-1dp"
            android:top="0dp">
    
            <shape android:shape="rectangle">
                <stroke
                    android:width="1dp"
                    android:color="#ffff0017"
                    android:dashGap="3dp"
                    android:dashWidth="1dp" />
    
                <solid android:color="@android:color/transparent" />
    
                <padding
                    android:bottom="10dp"
                    android:left="10dp"
                    android:right="10dp"
                    android:top="10dp" />
            </shape>
        </item>
</layer-list>

Set as background of your view:

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@drawable/view_line_dotted" />

Solution 5 - Android

What I did when I wanted to draw a dotted line is to define a drawable dash_line.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="line" >
<stroke
    android:dashGap="3dp"
    android:dashWidth="2dp"
    android:width="1dp"
    android:color="@color/black" />
</shape>

And then in the layout just define a view with background as dash_line. Note to include android:layerType="software", otherwise it won't work.

<View
            android:layout_width="match_parent"
            android:layout_height="5dp"
            android:background="@drawable/dash_line"
            android:layerType="software" />

Solution 6 - Android

I have custom a dashline which support horizontal&verical dash line . code below:

public class DashedLineView extends View
{
private float density;
private Paint paint;
private Path path;
private PathEffect effects;

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

public DashedLineView(Context context, AttributeSet attrs)
{
    super(context, attrs);
    init(context);
}

public DashedLineView(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context)
{
    density = DisplayUtil.getDisplayDensity(context);
    paint = new Paint();
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(density * 4);
    //set your own color
    paint.setColor(context.getResources().getColor(R.color.XXX));
    path = new Path();
    //array is ON and OFF distances in px (4px line then 2px space)
    effects = new DashPathEffect(new float[] { 4, 2, 4, 2 }, 0);

}

@Override
protected void onDraw(Canvas canvas)
{
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    paint.setPathEffect(effects);
    int measuredHeight = getMeasuredHeight();
    int measuredWidth = getMeasuredWidth();
    if (measuredHeight <= measuredWidth)
    {
        // horizontal
        path.moveTo(0, 0);
        path.lineTo(measuredWidth, 0);
        canvas.drawPath(path, paint);
    }
    else
    {
        // vertical
        path.moveTo(0, 0);
        path.lineTo(0, measuredHeight);
        canvas.drawPath(path, paint);
    }

}
}

Solution 7 - Android

If you are looking for a vertical line use this drawable.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:top="-8dp"
        android:bottom="-8dp"
        android:left="-8dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke
                android:width="4dp"
                android:color="#ffffff"
                android:dashGap="4dp"
                android:dashWidth="4dp"/>
        </shape>
    </item>
</layer-list>

The negative top bottom and left values remove the unwanted sides of the shape leaving a single dashed line.

Use it in a view like so.

<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:background="@drawable/dash_line_vertical"
android:layerType="software" />

Solution 8 - Android

By using this class you can apply "dashed and underline" effect to multiple lines text. to use DashPathEffect you have to turn off hardwareAccelerated of your TextView(though DashPathEffect method has a problem with long text). you can find my sample project here: https://github.com/jintoga/Dashed-Underlined-TextView/blob/master/Untitled.png.

public class DashedUnderlineSpan implements LineBackgroundSpan, LineHeightSpan {

    private Paint paint;
    private TextView textView;
    private float offsetY;
    private float spacingExtra;

    public DashedUnderlineSpan(TextView textView, int color, float thickness, float dashPath,
                               float offsetY, float spacingExtra) {
        this.paint = new Paint();
        this.paint.setColor(color);
        this.paint.setStyle(Paint.Style.STROKE);
        this.paint.setPathEffect(new DashPathEffect(new float[] { dashPath, dashPath }, 0));
        this.paint.setStrokeWidth(thickness);
        this.textView = textView;
        this.offsetY = offsetY;
        this.spacingExtra = spacingExtra;
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v,
                             Paint.FontMetricsInt fm) {
        fm.ascent -= spacingExtra;
        fm.top -= spacingExtra;
        fm.descent += spacingExtra;
        fm.bottom += spacingExtra;
    }

    @Override
    public void drawBackground(Canvas canvas, Paint p, int left, int right, int top, int baseline,
                               int bottom, CharSequence text, int start, int end, int lnum) {
        int lineNum = textView.getLineCount();
        for (int i = 0; i < lineNum; i++) {
            Layout layout = textView.getLayout();
            canvas.drawLine(layout.getLineLeft(i), layout.getLineBottom(i) - spacingExtra + offsetY,
                    layout.getLineRight(i), layout.getLineBottom(i) - spacingExtra + offsetY,
                    this.paint);
        }
    }
}

Result:

dashed underline

Solution 9 - Android

For a Dotted effect on a Canvas, set this attribute to the paint object :

paint.setPathEffect(new DashPathEffect(new float[] {0,30}, 0));

And change the value 30 as your render suits you : it represents the "distance" between each dots.

enter image description here

Solution 10 - Android

I have used the below as a background for the layout:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
<stroke
   android:width="1dp"
    android:dashWidth="10px"
   android:dashGap="10px"
    android:color="android:@color/black" 
   />
</shape>

Solution 11 - Android

I have created dashed dotted line for EditText. Here you go. Create your new xml. e.g dashed_border.xml Code here:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:bottom="1dp"
    android:left="-2dp"
    android:right="-2dp"
    android:top="-2dp">
    <shape android:shape="rectangle">
        <stroke
            android:width="2dp"
            android:color="#000000"
            android:dashGap="3dp"
            android:dashWidth="1dp" />

        <solid android:color="#00FFFFFF" />

        <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp" />
    </shape>
</item></layer-list>

And use your new xml file in your EditText for example:

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dashed_border"/>

Cheers! :)

Solution 12 - Android

None of these answers worked for me. Most of these answers give you a half-transparent border. To avoid this, you need to wrap your container once again with another container with your preferred color. Here is an example:

This is how it looks

dashed_border_layout.xml

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/black"
android:background="@drawable/dashed_border_out">
<LinearLayout
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:padding="5dp"
    android:background="@drawable/dashed_border_in"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is&#10;Dashed Container"
        android:textSize="16sp" />
</LinearLayout>

dashed_border_in.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape>
        <corners android:radius="10dp" />
        <solid android:color="#ffffff" />
        <stroke
            android:dashGap="5dp"
            android:dashWidth="5dp"
            android:width="3dp"
            android:color="#0000FF" />
        <padding
            android:bottom="5dp"
            android:left="5dp"
            android:right="5dp"
            android:top="5dp" />
    </shape>
</item>

dashed_border_out.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape>
        <corners android:radius="12dp" />
    </shape>
</item>

Solution 13 - Android

Use a ShapeDrawable instead of a LinearLayout and play with dashWidth and dashGap

http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

Solution 14 - Android

I liked the solution from Ruidge, but I needed more control from XML. So I changed it to Kotlin and added attributes.

  1. Copy the Kotlin class:

    import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.View

    class DashedDividerView : View { constructor(context: Context) : this(context, null, 0) constructor(context: Context, attributeSet: AttributeSet) : this(context, attributeSet, 0)

    companion object { const val DIRECTION_VERTICAL = 0 const val DIRECTION_HORIZONTAL = 1 }

    private var dGap = 5.25f private var dWidth = 5.25f private var dColor = Color.parseColor("#EE0606") private var direction = DIRECTION_HORIZONTAL private val paint = Paint() private val path = Path()

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( context, attrs, defStyleAttr ) { val typedArray = context.obtainStyledAttributes( attrs, R.styleable.DashedDividerView, defStyleAttr, R.style.DashedDividerDefault )

     dGap = typedArray.getDimension(R.styleable.DashedDividerView_dividerDashGap, dGap)
     dWidth = typedArray.getDimension(R.styleable.DashedDividerView_dividerDashWidth, dWidth)
     dColor = typedArray.getColor(R.styleable.DashedDividerView_dividerDashColor, dColor)
     direction =
         typedArray.getInt(R.styleable.DashedDividerView_dividerDirection, DIRECTION_HORIZONTAL)
    
     paint.color = dColor
     paint.style = Paint.Style.STROKE
     paint.pathEffect = DashPathEffect(floatArrayOf(dWidth, dGap), 0f)
     paint.strokeWidth = dWidth
    
     typedArray.recycle()
    

    }

    override fun onDraw(canvas: Canvas) { super.onDraw(canvas) path.moveTo(0f, 0f)

     if (direction == DIRECTION_HORIZONTAL) {
         path.lineTo(measuredWidth.toFloat(), 0f)
     } else {
         path.lineTo(0f, measuredHeight.toFloat())
     }
     canvas.drawPath(path, paint)
    

    }

    }

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

  3. Add a style to the styles file

  4. Now you can use the default style

    or set attributes in XML

Solution 15 - Android

The only thing that worked for me and I think it is the simplest way is using a Path with a paint object like this:

    Paint paintDash = new Paint();
    paintDash.setARGB(255, 0, 0, 0);
	paintDash.setStyle(Paint.Style.STROKE);
	paintDash.setPathEffect(new DashPathEffect(new float[]{10f,10f}, 0));
	paintDash.setStrokeWidth(2);
    Path pathDashLine = new Path();

Then onDraw(): (important call reset if you change those points between ondraw calls, cause Path save all the movements)

    pathDashLine.reset();
	pathDashLine.moveTo(porigenX, porigenY);
	pathDashLine.lineTo(cursorX,cursorY);
	c.drawPath(pathDashLine, paintDash);

Solution 16 - Android

Best Solution for Dotted Background working perfect

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
  <stroke
    android:dashGap="3dp"
    android:dashWidth="2dp"
    android:width="1dp"
    android:color="@color/colorBlack" />
</shape>

Solution 17 - Android

I dont know why but the voted answers don't work for me. I write it this way and works good.
Define a custom view:

public class XDashedLineView extends View {

private Paint   mPaint;
private Path    mPath;
private int     vWidth;
private int     vHeight;

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

public XDashedLineView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public XDashedLineView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    mPaint = new Paint();
    mPaint.setColor(Color.parseColor("#3F577C"));
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setPathEffect(new DashPathEffect(new float[] {10,10}, 0));
    mPath = new Path();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    this.vWidth = getMeasuredWidth();
    this.vHeight = getMeasuredHeight();
    mPath.moveTo(0, this.vHeight / 2);
    mPath.quadTo(this.vWidth / 2, this.vHeight / 2, this.vWidth, this.vHeight / 2);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath, mPaint);
}
}

Then you can use it in your xml:

        <com.YOUR_PACKAGE_NAME.XDashedLineView
        android:layout_width="690dp"
        android:layout_height="1dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="620dp"/>

Solution 18 - Android

I've created a library with a custom view to solve this issue, and it should be very simple to use. See https://github.com/Comcast/DahDit for more. You can add dashed lines like this:

<com.xfinity.dahdit.DashedLine
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    app:dashHeight="4dp"
    app:dashLength="8dp"
    app:minimumDashGap="3dp"
    app:layout_constraintRight_toRightOf="parent"
    android:id="@+id/horizontal_dashes"/>

Solution 19 - Android

Similar to tier777 here is a solution for a horizontal line:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="-1dp">
        <shape android:shape="line">
            <stroke
                android:width="1dp"
                android:color="#111"
                android:dashWidth="8dp"
                android:dashGap="2dp"
                />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</layer-list>

The clue is <item android:top="-1dp">.

In order to show dashed line on old devices (<= API 21) you should create a view with android:layerType="software" (see https://stackoverflow.com/questions/10843402/android-dashed-line-drawable-potential-ics-bug):

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@drawable/dashed_line"
    android:layerType="software"
    />

Also you can add the same view without android:layerType="software" to layout-v23 for better performance, but I am not sure it will work on all devices with API 23.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJason RobinsonView Question on Stackoverflow
Solution 1 - AndroidemboView Answer on Stackoverflow
Solution 2 - AndroidsiliconeagleView Answer on Stackoverflow
Solution 3 - AndroidSargamView Answer on Stackoverflow
Solution 4 - Androidtier777View Answer on Stackoverflow
Solution 5 - AndroidTony VuView Answer on Stackoverflow
Solution 6 - AndroidruidgeView Answer on Stackoverflow
Solution 7 - AndroidDuncan HogganView Answer on Stackoverflow
Solution 8 - AndroidNguyen Quoc DatView Answer on Stackoverflow
Solution 9 - AndroidArnaudView Answer on Stackoverflow
Solution 10 - AndroidudaiView Answer on Stackoverflow
Solution 11 - AndroidWiktor KalinowskiView Answer on Stackoverflow
Solution 12 - AndroidYunus EmreView Answer on Stackoverflow
Solution 13 - AndroidvieuxView Answer on Stackoverflow
Solution 14 - AndroidIgorView Answer on Stackoverflow
Solution 15 - AndroidtakluiperView Answer on Stackoverflow
Solution 16 - AndroidArun PrajapatiView Answer on Stackoverflow
Solution 17 - AndroidKyesonView Answer on Stackoverflow
Solution 18 - AndroidCalvinView Answer on Stackoverflow
Solution 19 - AndroidCoolMindView Answer on Stackoverflow