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.
This question is related to
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);
}
}
}
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"/>
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 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.
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" />
Use a ShapeDrawable instead of a LinearLayout and play with dashWidth and dashGap
http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape
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>
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! :)
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"/>
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"/>
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:
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 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>
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" />
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
<declare-styleable name="DashedDividerView">
<attr name="dividerDashGap" format="dimension" />
<attr name="dividerDashWidth" format="dimension" />
<attr name="dividerDashColor" format="reference|color" />
<attr name="dividerDirection" format="enum">
<enum name="vertical" value="0" />
<enum name="horizontal" value="1" />
</attr>
</declare-styleable>
3) Add a style to the styles file
<style name="DashedDividerDefault">
<item name="dividerDashGap">2dp</item>
<item name="dividerDashWidth">2dp</item>
<!-- or any color -->
<item name="dividerDashColor">#EE0606</item>
<item name="dividerDirection">horizontal</item>
</style>
4) Now you can use the default style
<!-- here will be your path to the class -->
<com.your.package.app.DashedDividerView
android:layout_width="match_parent"
android:layout_height="2dp"
/>
or set attributes in XML
<com.your.package.app.DashedDividerView
android:layout_width="match_parent"
android:layout_height="2dp"
app:dividerDirection="horizontal"
app:dividerDashGap="2dp"
app:dividerDashWidth="2dp"
app:dividerDashColor="@color/light_gray"/>
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>
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);
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:
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" />
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.
Source: Stackoverflow.com