it-swarm.com.de

Zusätzliches Auffüllen von TextView mit HTML-Inhalten

Ich habe diese TextView:

<TextView
    Android:id="@+id/issue_journal_item_notes"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_alignLeft="@+id/issue_journal_item_details"
    Android:layout_below="@+id/issue_journal_item_details"
    Android:background="@drawable/journal_item_notes_background"
    Android:padding="8dp"
    Android:text="issue_journal_item_notes"
    Android:textIsSelectable="true" />

Ich fülle das mit:

String html = "<p>Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.Android.com/sdk/index.html<br/>(needed for logcat)</p>";
theTextView.setText(Html.fromHtml(html));

Das führt zu:

Resulting screenshot

"Beauftragter ..." ist eine andere TextView.
Meine TextView ist die mit dem grauen Hintergrund. Seine Grenzen sind deutlich mit dem sehr hellen Grau zu sehen. Der linke dunkelgraue Balken links ist Teil des Hintergrunds, daher ist es auch die TextView

Wir können das 8-dpi-Quadrat-Polster deutlich erkennen. Was ist jedoch der leere Raum am unteren Rand? Es ist eine Art Auffüllung, aber ich habe dies weder in XML noch in Code festgelegt!

Für den Fall, dass jemand fragt, ich braucheHTML-Unterstützung, da der Inhalt im Gegensatz zum oben gezeigten Screenshot möglicherweise HTML-Inhalte enthält (<pre>, <i>, <b> usw.).

30
Benoit Duffez

Das zusätzliche 'Auffüllen', das Sie sehen, ist in der Tat nur ein Zeilenumbruch, gefolgt von einem weiteren Zeilenumbruch:

enter image description here

Wenn Sie sich mit der Implementierung von Html.fromHtml(...) befassen, werden Sie auf die folgende Methode stoßen, die Absatz-Tags behandelt:

private static void handleP(SpannableStringBuilder text) {
    int len = text.length();

    if (len >= 1 && text.charAt(len - 1) == '\n') {
        if (len >= 2 && text.charAt(len - 2) == '\n') {
            return;
        }

        text.append("\n");
        return;
    }

    if (len != 0) {
        text.append("\n\n");
    }
}

Das obige Snippet stammt aus der Android 4.2.2-Quelle . Die Logik ist recht einfach und stellt im Grunde sicher, dass jedes Absatz-Tag mit \n\n endet, um eine visuelle Lücke zwischen zwei Elementblöcken zu schaffen. Dies bedeutet, dass das Framework nicht berücksichtigt, ob der gesamte HTML-Text nur aus einem einzigen Absatz (in Ihrem Fall) oder aus mehreren aufeinanderfolgenden Paragaps besteht. Am Ende eines transformierten Absatzes werden immer zwei Zeilenumbrüche angezeigt .

Wenn Sie jedoch wissen, dass Sie es immer mit einem einzelnen Absatz zu tun haben, ist es am einfachsten, diesen umschließenden Absatz zu entfernen, bevor Sie ihn an Html.fromHtml(...) weiterleiten. Dies ist so ziemlich das, was in einer der anderen Antworten vorgeschlagen wurde.

Da Sie bereits erwähnt haben, dass dies keine Option ist, besteht die Alternative darin, das Ergebnis von Html.fromHtml(...) zu "kürzen" und alle nachgestellten Leerzeichen zu entfernen. Android gibt eine Spanned (in der Regel ist dies ein SpannableStringBuilder Objekt), die leider nicht kommt mit einem eingebauten in trim() Verfahren. Es ist jedoch nicht zu schwierig, eine eigene zu finden oder eine von mehreren verfügbaren Implementierungen auszuleihen.

Eine grundlegende Implementierung für eine trim()-Methode würde ungefähr so ​​aussehen:

public static CharSequence trim(CharSequence s, int start, int end) {
    while (start < end && Character.isWhitespace(s.charAt(start))) {
        start++;
    }

    while (end > start && Character.isWhitespace(s.charAt(end - 1))) {
        end--;
    }

    return s.subSequence(start, end);
}

Ändern Sie dazu Ihren ursprünglichen Code in:

String html = "<p>Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.Android.com/sdk/index.html<br/>(needed for logcat)</p>";
CharSequence trimmed = trim(Html.fromHtml(html));
theTextView.setText(trimmed);

Und voilà, vorher und nachher:

enter image description here

53
MH.

Sie können auch den folgenden Code verwenden

 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;
}
13
Kirtikumar A.

Html.fromHtml(html) gibt Spannable zurück, sodass Sie dies in einen String konvertieren können, indem Sie toString() then trim aufrufen und den String dann auf textview setzen.

String html = "<p>Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.Android.com/sdk/index.html<br/>(needed for logcat)</p>";
theTextView.setText(Html.fromHtml(html).toString().trim());
4
Praveena

Das Verarbeiten von HTML-Tags führt dazu, dass Zeilenumbrüche \n hinzugefügt werden und manchmal mehrere \n aufeinander folgen. Das Ergebnis ist eine Zeichenfolge mit mehreren Zeilenumbrüchen zwischen dem Text (insbesondere, wenn die HTML-Zeichenfolge das Tag <br/> enthält).

Die folgende Methode entfernt führende und nachfolgende Zeilenumbrüche, die aus <br/> tag. resultieren.

Reduziert außerdem mehrere neue Zeilen zwischen Text (API> 24).

/**
 *
 * @param htmlString
 * @return Spanned represents the html string removed leading and trailing newlines. Also, reduced newlines resulted from processing HTML tags (for API >24)
 */
public static Spanned processHtmlString(String htmlString){

    // remove leading <br/>
    while (htmlString.startsWith("<br/>")){

        htmlString = htmlString.replaceFirst("<br/>", "");
    }

    // remove trailing <br/>
    while (htmlString.endsWith("<br/>")){

        htmlString =  htmlString.replaceAll("<br/>$", "");
    }

    // reduce multiple \n in the processed HTML string 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

        return Html.fromHtml(htmlString,  FROM_HTML_MODE_COMPACT);
    }else{

        return Html.fromHtml(htmlString);
    }
}
0
Islam Assi

Versuchen Sie dies, indem Sie das Tag <p> entfernen.

String html = "Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.Android.com/sdk/index.html<br/>(needed for logcat)";
theTextView.setText(Html.fromHtml(html));

Hoffe, es funktioniert.

0
Oam

Wie ist das Layout um Ihre TextView? Ich erinnere mich, dass einige Layouts die bevorzugte Höhe Ihres Bauteils ignorieren und es einfach anpassen.

0
Jeroen Peeters