xtreak
xtreak

Reputation: 1376

<hr> tag usage in android

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


tag effect in android using supported tags.

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

Answers (6)

Vishnu M.
Vishnu M.

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.

Java

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);
    }
}

Kotlin

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

NareshRavva
NareshRavva

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

cjds
cjds

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

18446744073709551615
18446744073709551615

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

Amit Prajapati
Amit Prajapati

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

rachit
rachit

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

Related Questions