Reputation: 1376
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..
Upvotes: 8
Views: 7066
Reputation: 971
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.
Upvotes: 20
Reputation: 863
hr tag is not supported in Android, My suggestion is do like this if u want line
in Activity:
TextView tt = (TextView)findViewById(R.id.textView1);
LinearLayout LL = (LinearLayout)findViewById(R.id.ll1);
String message = "Hello <br> hai<br> I am fine <hr>";
tt.setText(Html.fromHtml(message));
View hLine = new View(this);
hLine .setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 1));
hLine .setBackgroundColor(Color.WHITE);
LL.addView(hLine );
in Xml:
<LinearLayout
android:id="@+id/ll1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="textView1"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Upvotes: 0
Reputation: 379
Android Html.fromHTML does not support all tags.
If you want such tags I suggest you use a WebView instead
WebView webview = new WebView(this);
String summary = "<html><body>Sorry, <span style=\"background: red;\">Madonna</span> gave no results</body></html>";
webview.loadData(summary, "text/html", "utf-8");
A WebView will allow you to have HR or whatever tag you like
Upvotes: 1
Reputation: 16832
You add a view of height 1 or 2, width set to match parent, and specify the background color. But that means you will have 3 text views.
This is from working code. As you see, any child of view will do:
<!-- divider 1 -->
<LinearLayout
android:id="@+id/lineA"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#000000" />
Another option is to use a WebView which definitely does support <hr>, but that most likely will be an overkill.
Upvotes: -1
Reputation: 14315
Try this for horizontal line
View line = new View(this);
line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 1));
line.setBackgroundColor(Color.rgb(51, 51, 51));
layout.addView(line);
Upvotes: 0
Reputation: 1996
hr tag is not supported in Android. you will have to add a separate view for the horizontal line with background color as your text.
Upvotes: 0