I have a statement to for which I have to add up an horizontal line. But its not supported by android it seems is there any way to recreate the
String message = "Hello <br> hai<br> I am fine <hr>";
tab.setText(Html.fromHtml(message));
It shows
Hello
hai
I am fine
But no horizontal line.
Here the HTML tag of "hr" is not working. Are there any ways to add hr tag effect from the supported tags. Thanks in advance..
Html.fromHtml()
doesn't support the <hr>
tag at the moment so you will need to write your own tag handler that implements Html.TagHandler
. TextViews in Android are styled using Spans, so we will need to create a Span that draws a horizontal line as well, let's call it HrSpan
.
String html = "Hello <br> hai<br> I am fine <hr> And here's another line";
HtmlTagHandler tagHandler = new HtmlTagHandler();
Spanned styledText = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY, null, tagHandler);
textView.setText(styledText);
HtmlTagHandler.java
public class HtmlTagHandler implements Html.TagHandler {
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equals("hr")) {
handleHrTag(opening, output);
}
}
private void handleHrTag(boolean opening, Editable output) {
final String placeholder = "\n-\n";
if (opening) {
output.insert(output.length(), placeholder);
} else {
output.setSpan(new HrSpan2(), output.length() - placeholder.length(), output.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
HrSpan.java
public class HrSpan extends ReplacementSpan {
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
return 0;
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(8); // 8px tall line
int middle = (top + bottom) / 2;
// Draw a line across the middle of the canvas
canvas.drawLine(0, middle, canvas.getWidth(), middle, paint);
}
}
val html = "Hello <br> hai<br> I am fine <hr> Another line here <hr><hr>"
val tagHandler = HtmlTagHandler()
textView.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY, null, tagHandler)
class HtmlTagHandler : Html.TagHandler {
override fun handleTag(opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader?) {
if (output == null) return
when (tag) {
"hr" -> handleHrTag(opening, output)
// Handle other tags if needed
}
}
private fun handleHrTag(opening: Boolean, output: Editable) {
val placeholder = "\n-\n" // Makes sure the HR is drawn on a new line
if (opening) {
output.insert(output.length, placeholder)
} else {
output.setSpan(HrSpan(), output.length - placeholder.length, output.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
class HrSpan : ReplacementSpan() {
override fun getSize(paint: Paint, text: CharSequence?, start: Int, end: Int, fm: Paint.FontMetricsInt?) = 0
override fun draw(
canvas: Canvas, text: CharSequence?, start: Int, end: Int, x: Float, top: Int, y: Int,
bottom: Int, paint: Paint
) {
paint.style = Paint.Style.STROKE
paint.strokeWidth = 8f
// Draw line in the middle of the available space
val middle = ((top + bottom) / 2).toFloat()
canvas.drawLine(0f, middle, canvas.width.toFloat(), middle, paint)
}
}
This should give you a result something like this. It matches the width of your TextView so change the TextView width attribute to match_parent if you want the line to take up the full width.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With