Solution 1
1 - Create a drawable for the dashes. Like this:
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp" />
<solid android:color="@android:color/transparent" />
<stroke
android:color="@android:color/black"
android:dashWidth="20px"
android:dashGap="10px"
android:width="3dp"/>
</shape>
2 - Set it as the background of your text view, it can be just a word.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello!"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_shape"
android:padding="4dp"
android:text="world!"/>
</LinearLayout>
The result:
Important note: This solution is going to work only for small text, like show a score in a game or small messagens. It won't adapt to big texts.
Solution 2
If you need a more complex solution that works for big texts, you can use a Spannable.
1 -> Create a custom ReplacementSpan
public class DashedBorderSpan extends ReplacementSpan {
private Drawable mDrawable;
private int mPadding;
public DashedBorderSpan(Drawable drawable, int padding) {
super();
mDrawable = drawable;
mPadding = padding;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
RectF rect = new RectF(x - mPadding, top - mPadding, x + measureText(paint, text, start, end) + mPadding, bottom + mPadding);
mDrawable.setBounds((int) rect.left, (int)rect.top, (int)rect.right, (int)rect.bottom);
canvas.drawText(text, start, end, x, y, paint);
mDrawable.draw(canvas);
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return Math.round(paint.measureText(text, start, end));
}
private float measureText(Paint paint, CharSequence text, int start, int end) {
return paint.measureText(text, start, end);
}
}
2 -> Apply the Spannable
TextView textView = (TextView) findViewById(R.id.textasd);
String hello = "Dashed!";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
stringBuilder.append(hello);
stringBuilder.setSpan(new DrawableSpan(getDrawable(R.drawable.dashed_border_shape)),
0,
stringBuilder.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.append("not dashed... boring");
textView.setText(stringBuilder);
This solution will work for all the cases. It's a better solution, although it is more complicated.
Example
If you would like to use it with a place holder use it like this:
String someText = "Some Text!";
//R.string.placeholder = Hello: %s
String formatedText = String.format(getString(R.string.placeholder), someText);
SpannableStringBuilder stringBuilderPlaceHolder = new SpannableStringBuilder();
stringBuilderPlaceHolder.append(formatedText);
stringBuilderPlaceHolder.setSpan(new DashedBorderSpan(getDrawable(R.drawable.dashed_border_shape), 10),
formatedText.length() - someText.length(),
formatedText.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textViewPlaceHolder.setText(stringBuilderPlaceHolder);
Result:
This way the span will be set only on your place holder. If you have a more complex holder use the same logic to achieve what you need.
Edit
There's a small problem with the solution 2, but there is a solution.
You must take care with padding of the dashed border drawable. If you use padding in the dashed border, you will need to set padding in the TextView that uses the Span. In the image that the author of the question provided, you can see that the upper and bottom lines got cut (if you increase the padding, the lines will be completly gone), in order to avoid this use padding in your textview. Like this:
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="20dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="30dp"
android:paddingTop="3dp" <!-- This will fix the problem! -->
android:paddingBottom="3dp" <!-- This will fix the problem! -->
android:gravity="center_horizontal"
android:text="blabla"
android:textSize="20sp"/>
This will fix the problem =]
Happy coding!