Remove extra line breaks after Html.fromHtml()
Asked Answered
B

4

48

I am trying to place html into a TextView. Everything works perfectly, this is my code.

String htmlTxt = "<p>Hellllo</p>"; // the html is form an API
Spanned html = Html.fromHtml(htmlTxt);
myTextView.setText(html);

This sets my TextView with the correct html. But my problem is, having a

tag in the html, the result text that goes into the TextView has a "\n" at the end, so it pushes my TextView's height higher than it should be.

Since its a Spanned variable, I can't apply regex replace to remove the "\n", and if I was to convert it into a string, then apply regex, I lose the functionality of having html anchors to work properly.

Does anyone know any solutions to remove the ending linebreak(s) from a "Spanned" variable?

Boer answered 6/3, 2012 at 18:6 Comment(5)
Can you use actual HTML line breaks (<br/>) instead? You can place the line break before the text, and nothing after so it's: <br/>Hellllllllooooo , which will give it a break above the text, but nothing below it.Minnie
@Ben, the html return is from an API and I have no control over it.Boer
Maybe using TextUtils.getTrimmedLength() would work. There are a bunch of other functions in TextUtils that may help you solve the problem...Historicity
I've been battling this today. The answers below work fine as I wrote my own. The problem is when </p> tags are not just in the end but elsewhere in the text. The only way to do it is to convert to a string and do .replace(...) but then you loose all your formatting.Laurinelaurita
check this too , very simple way and works ;) https://mcmap.net/q/357326/-extra-line-breaks-at-end-of-textForint
T
62

Nice answer @Christine. I wrote a similar function to remove trailing whitespace from a CharSequence this afternoon:

/** Trims trailing whitespace. Removes any of these characters:
 * 0009, HORIZONTAL TABULATION
 * 000A, LINE FEED
 * 000B, VERTICAL TABULATION
 * 000C, FORM FEED
 * 000D, CARRIAGE RETURN
 * 001C, FILE SEPARATOR
 * 001D, GROUP SEPARATOR
 * 001E, RECORD SEPARATOR
 * 001F, UNIT SEPARATOR
 * @return "" if source is null, otherwise string with all trailing whitespace removed
 */
public static CharSequence trimTrailingWhitespace(CharSequence source) {

    if(source == null)
        return "";

    int i = source.length();

    // loop back to the first non-whitespace character
    while(--i >= 0 && Character.isWhitespace(source.charAt(i))) {
    }

    return source.subSequence(0, i+1);
}
Tights answered 17/4, 2012 at 8:12 Comment(2)
This is one place where IMO a do-while is more readable than a while: do { --i; } while (i >= 0 && Character.isWhitespace(cs.charAt(i))) (obviously, split it up into multiple lines -- StackOverflow won't let me do that in a comment)Singlefoot
I had issues using CharSequence so had to cast it back as Spanned e.g. temp = (Spanned) temp.subSequence(0, temp.length() - 2); // has "\n\n" at the endAbner
B
22

The spannable is a CharSequence, which you can manipulate.

This works:

    myTextView.setText(noTrailingwhiteLines(html));

    private CharSequence noTrailingwhiteLines(CharSequence text) {

        while (text.charAt(text.length() - 1) == '\n') {
            text = text.subSequence(0, text.length() - 1);
        }
        return text;
    }
Brokaw answered 2/4, 2012 at 10:15 Comment(2)
This is quite inefficient for SpannableStrings, as subSequence() creates a whole new SpannableString object. The accepted answer is much better.Singlefoot
When you make a tradeoff between programmer's time, code readability and program efficiency, it depends on the circumstances which version is better. I consider program efficiency the least relevant parameter, unless your code gets executed a thousand times per second on millions of devices.Brokaw
D
11

You can try this:

Spanned htmlDescription = Html.fromHtml(textWithHtml);
String descriptionWithOutExtraSpace = new String(htmlDescription.toString()).trim();

textView.setText(htmlDescription.subSequence(0, descriptionWithOutExtraSpace.length()));
Dendrite answered 3/3, 2016 at 21:32 Comment(4)
Aren't you losing the spans by converting the Spanned object to String?Bothy
@Bothy You're not returning the trimmed String, you're creating a subSequence of the spanned charSequence with the length of the trimmed String. You're not losing the spans.Lignin
this wouldn't work if there were leading spaces though, right? trim() removes both leading and trailing spacesBalanced
@Balanced You can use trimEnd function. It worked for me.Petrapetracca
F
2

you can use this lines ... totally works ;)

i know your problem solved but maybe some one find this useful .

try{
        string= replceLast(string,"<p dir=\"ltr\">", "");
        string=replceLast(string,"</p>", "");
}catch (Exception e) {}

and here is replaceLast ...

public String replceLast(String yourString, String frist,String second)
{
    StringBuilder b = new StringBuilder(yourString);
    b.replace(yourString.lastIndexOf(frist), yourString.lastIndexOf(frist)+frist.length(),second );
    return b.toString();
}
Forint answered 3/7, 2014 at 12:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.