Wie zeige ich HTML in TextView an?

756

Ich habe einfaches HTML :

<h2>Title</h2><br>
<p>description here</p>

Ich möchte HTML-Text anzeigen TextView. Wie macht man das?

UMAR
quelle
7
Möchten Sie die Tags anzeigen oder weglassen?
DerMike
1
Schauen
Nilanchal
1
Wenn Sie nach einer veralteten Lösung suchen, finden Sie sie hier. Stackoverflow.com/questions/37904739/…
crgarridos

Antworten:

1351

Sie müssen verwenden Html.fromHtml(), um HTML in Ihren XML-Zeichenfolgen zu verwenden. Das einfache Verweisen auf einen String mit HTML in Ihrem Layout-XML funktioniert nicht.

Folgendes sollten Sie tun:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    textView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>", Html.FROM_HTML_MODE_COMPACT));
} else { 
    textView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>"));
}
Johnny Five
quelle
7
h2per definitionem schafft sich viel Spielraum um sich herum. und pkommt auch mit etwas Spielraum. Wenn Sie die Lücke nicht möchten, sollten Sie andere HTML-Elemente verwenden.
David Hedlund
10
Kostadin, Sie können Tags in XML einfügen, Sie müssen sie nur in CDATA-Klammern setzen.
Gerard
3
Für diejenigen, die möchten, dass es mit den ol / ul / li-Tags funktioniert
Tiago
13
Das sollte sein android.text.Html.fromHtml. Ich weiß, dass die meisten IDEs das Problem für Sie beheben werden, aber aus Gründen der Lesbarkeit ist es besser, die Paketnamen zu kennen.
Martin
14
@ Martin Ich würde nicht für die Lesbarkeit sagen , sondern für die Vollständigkeit . Vollqualifizierte IMO-Namen, die direkt in Code wie diesem verwendet werden, sind weniger lesbar als Kurznamen. Aber ich stimme Ihnen darin zu, dass eine Antwort wie diese das Paket (auf einer Randnotiz) liefern sollte, das der Punkt des Links hier ist;)
Joffrey
76

setText (Html.fromHtml (bodyData)) ist nach API 24 veraltet . Jetzt müssen Sie Folgendes tun:

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
      tvDocument.setText(Html.fromHtml(bodyData,Html.FROM_HTML_MODE_LEGACY));
 } else {
      tvDocument.setText(Html.fromHtml(bodyData));
 }
Shohan Ahmed Sijan
quelle
4
Warum wird FROM_HTML_MODE_LEGACY in API 24+ verwendet?
Galcyurio
64

Schauen Sie sich das an: https://stackoverflow.com/a/8558249/450148

Es ist auch ziemlich gut !!

<resource>
    <string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>

Es funktioniert nur für wenige Tags.

Felipe Micaroni Lalli
quelle
12
Gibt es eine Liste von Tags, die von dieser Methode unterstützt werden?
Mente
23
@mente Laut Quellcode : <a>, <b>, <big>, <blockquote>, <br>, <cite>, <dfn> <div align = "...">, <em>, < font size = "..." color = "..." face = "..."> <h1-6>, <i>, <img src = "...">, <p>, <small > <strike>, <strong>, <sub>, <sup>, <tt>, <u> (Quelle: dzone.com/snippets/how-display-html-android )
JerabekJakub
@ JerabekJakub aber pass auf, wenn du mit img umgehen willst, musst du Html.ImageGetter implementieren.
MiguelHincapieC
@ 0mahc0 Wenn man img implementiert, ist es möglich, die Größe einzustellen?
Joh
1
@Joh ja es ist möglich. Wenn Sie .ImageGetter implementieren, gibt es eine Methode namens getDrawable (String source). Wenn du mehr Hilfe brauchst, erstelle eine Frage und tagge mich, ich werde dir ein Beispiel geben;)
MiguelHincapieC
41

Wenn Sie es über XML ohne Änderungen im Java-Code konfigurieren möchten, ist diese Idee möglicherweise hilfreich. Sie rufen einfach init vom Konstruktor auf und legen den Text als HTML fest

public class HTMLTextView extends TextView {
    ... constructors calling init...
    private void init(){
       setText(Html.fromHtml(getText().toString()));
    }    
}

xml:

<com.package.HTMLTextView
android:text="@string/about_item_1"/>
Benutzer1299412
quelle
1
Was ist '...'. Bitte klären Sie
GilbertS
25

Wenn Sie versuchen, HTML von einer Zeichenfolgenressourcen-ID anzuzeigen, wird die Formatierung möglicherweise nicht auf dem Bildschirm angezeigt. Wenn Ihnen dies passiert, versuchen Sie stattdessen, CDATA-Tags zu verwenden:

strings.xml:
<string name="sample_string"><![CDATA[<h2>Title</h2><br><p>Description here</p>]]></string>

...

MainActivity.java:
text.setText(Html.fromHtml(getString(R.string.sample_string));

Siehe diesen Beitrag für weitere Details.

Phileo99
quelle
Danke, das hat es für mich getan - mit API 23.
XMAN
24

Der folgende Code ergab das beste Ergebnis für mich.

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
Rajiv Manivannan
quelle
13
String value = "<html> <a href=\"http://example.com/\">example.com</a> </html>";
    SiteLink= (TextView) findViewById(R.id.textViewSite);
    SiteLink.setText(Html.fromHtml(value));
    SiteLink.setMovementMethod(LinkMovementMethod.getInstance());
Pedro
quelle
Wie ändert man die Farbe des Ankers?
EdmundYeung99
android: textColorLink = "Farbe"
Pedro
Dadurch wird die gesamte Textansicht rot gefärbt. Wenn ich jedoch nur die Ankertags verwenden möchte, muss ich das <a> -Tag mit <font> -Tags
umschließen
11

Wenn Sie nur HTML-Text anzeigen möchten und keinen wirklich benötigen TextView, nehmen Sie einen WebViewund verwenden Sie ihn wie folgt:

String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);

Dies beschränkt Sie auch nicht auf einige HTML-Tags.

prom85
quelle
2
Zwar ist dies eine sehr nützliche Art und Weise ist es, den eingeschränkten Satz von HTML - Tags zu umgehen, von Textview unterstützt wird , hat es den Nachteil , dass es nicht gut funktioniert mit layout_height="wrap_content". Sie müssen stattdessen eine explizite Höhe oder match_parent festlegen.
Ridcully
3
Webview ist sehr langsam
Jackky777
11

Der beste Ansatz, um CData-Abschnitte für die Zeichenfolge in der Datei strings.xml zu verwenden, um eine tatsächliche Anzeige des HTML-Inhalts in der Textansicht zu erhalten. Das folgende Codefragment gibt Ihnen eine gute Vorstellung.

//in string.xml file
<string name="welcome_text"><![CDATA[<b>Welcome,</b> to the forthetyroprogrammers blog Logged in as:]]> %1$s.</string>

//and in Java code
String welcomStr=String.format(getString(R.string.welcome_text),username);
tvWelcomeUser.setText(Html.fromHtml(welcomStr));

Der CData-Abschnitt im Zeichenfolgentext behält die HTML-Tag-Daten auch nach dem Formatieren von Text mit der String.format-Methode bei. Html.fromHtml (str) funktioniert also einwandfrei und Sie sehen den fetten Text in der Begrüßungsnachricht.

Ausgabe:

Willkommen in Ihrem Lieblings-Musik-App-Store. Eingeloggt als: Benutzername

Rajendhiran Easu
quelle
Danke, das hat es für mich getan - mit API 23.
XMAN
danke, du hast meinen Tag gerettet :) Nur eine kleine Ergänzung: Wir müssen diese Prüfung zum obigen Code hinzufügen: if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.N) {// für 24 API und mehr textView.setText ( Html.fromHtml (welcomStr, Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else {// oder für ältere API textView.setText (Html.fromHtml (welcomStr)); }. Der Wert für das 2. Parameterflag für API> = 24 kann beliebig sein.
AndroidGuy
6

Ich möchte auch folgendes Projekt vorschlagen: https://github.com/NightWhistler/HtmlSpanner

Die Verwendung entspricht fast der des Standard-Android-Konverters:

(new HtmlSpanner()).fromHtml()

Ich habe es gefunden, nachdem ich bereits mit der eigenen Implementierung von HTML in einen spannbaren Konverter begonnen habe, da Standard-HTML.fromHtml nicht genügend Flexibilität hinsichtlich der Rendersteuerung bietet und sogar keine Möglichkeit bietet, benutzerdefinierte Schriftarten von ttf zu verwenden

Fedotchenco Denis
quelle
Ich erhalte folgende Fehlermeldung: Fehler: (80, 13) Fehler beim Auflösen: com.osbcp.cssparser: cssparser: 1.5 Wie kann ich das beheben?
Araju
6

Ich weiß, dass diese Frage alt ist. Andere Antworten hier schlagen Html.fromHtml()Methode vor. Ich empfehle Ihnen, HtmlCompat.fromHtml()aus androidx.core.text.HtmlCompatPaket zu verwenden. Da dies eine abwärtskompatible Version der HtmlKlasse ist.

Beispielcode:

import androidx.core.text.HtmlCompat;
import android.text.Spanned;
import android.widget.TextView;

String htmlString = "<h1>Hello World!</h1>";

Spanned spanned = HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_COMPACT);

TextView tvOutput = (TextView) findViewById(R.id.text_view_id);

tvOutput.setText(spanned);

Auf diese Weise können Sie die Überprüfung der Android-API-Version vermeiden und sie ist einfach zu verwenden (einzeilige Lösung).

Shashanth
quelle
Wie unterscheidet sich das von alten Methoden? Was ist der Zweck des HTML-Modus?
user1209216
1
War auf der Suche nach so etwas. Danke :)
Subhrajyoti Sen
5

Einfache Verwendung Html.fromHtml("html string"). Das wird funktionieren. Wenn die Zeichenfolge Tags wie enthält, werden <h1>Leerzeichen eingefügt. Aber wir können diese Räume nicht beseitigen. Wenn Sie die Leerzeichen dennoch entfernen möchten, können Sie die Tags in der Zeichenfolge entfernen und die Zeichenfolge dann an die Methode übergeben Html.fromHtml("html string");. Auch im Allgemeinen stammen diese Zeichenfolgen vom Server (dynamisch), aber nicht oft, wenn es besser ist, die Zeichenfolge an die Methode zu übergeben, als zu versuchen, die Tags aus der Zeichenfolge zu entfernen.

nole
quelle
4
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Samuel Gildas
quelle
4

Erstellen Sie eine globale Methode wie:

public static Spanned stripHtml(String html) {
            if (!TextUtils.isEmpty(html)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    return Html.fromHtml(html, Html.FROM_HTML_MODE_COMPACT);
                } else {
                    return Html.fromHtml(html);
                }
            }
            return null;
        }

Sie können es auch in Ihrer Aktivität / Ihrem Fragment verwenden, wie:

text_view.setText(stripHtml(htmlText));
Shylendra Madda
quelle
3

Ich habe dies mit der Webansicht implementiert. In meinem Fall muss ich das Bild von der URL zusammen mit dem Text in der Textansicht laden und das funktioniert für mich.

WebView myWebView =new WebView(_context);
        String html = childText;
        String mime = "text/html";
        String encoding = "utf-8";
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.loadDataWithBaseURL(null, html, mime, encoding, null);
Mörder
quelle
Für eine ordnungsgemäße Anzeige von UTF-8 müssen Sie den MIME-Typ auf "text / html; charset = UTF-8" setzen.
Shawkinaw
3

Es wurde durch verschiedene Antworten vorgeschlagen, die hier vorgeschlagene HTML- Framework-Klasse zu verwenden , aber leider hat diese Klasse in verschiedenen Versionen von Android und verschiedenen nicht behobenen Fehlern ein unterschiedliches Verhalten, wie in den Ausgaben 214637 , 14778 , 235128 und 75953 gezeigt .

Daher möchten Sie möglicherweise eine Kompatibilitätsbibliothek verwenden, um die HTML-Klasse für alle Android-Versionen zu standardisieren und zurück zu portieren. Diese enthält weitere Rückrufe für Elemente und das Design:

Github-Projekt HtmlCompat

Obwohl es der HTML-Klasse des Frameworks ähnelt, waren einige Signaturänderungen erforderlich, um mehr Rückrufe zu ermöglichen. Hier ist das Beispiel von der GitHub-Seite:

Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0);
// You may want to provide an ImageGetter, TagHandler and SpanCallback:
//Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0,
//        imageGetter, tagHandler, spanCallback);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(fromHtml);
Paul Lammertsma
quelle
@MartijnPieters Die zuvor geschlossene Antwort war ein Duplikat einer Antwort auf diese Frage in Bezug auf die Ablehnung einer Framework-Methode . Ich habe den Grund erweitert, warum die Verwendung einer Kompatibilitätsbibliothek ein besserer Ansatz wäre. Ich denke nicht, dass es vernünftig ist, eine der Fragen als Duplikate voneinander zu kennzeichnen, da sie sich deutlich unterscheiden.
Paul Lammertsma
2

Wenn Sie eine benutzerdefinierte Textansicht schreiben, wird die grundlegende HTML-Set-Textfunktion von einigen Geräten ausgeblendet.

Wir müssen also die folgenden zusätzlichen Schritte ausführen, damit es funktioniert

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}
Vinayak
quelle
1
public class HtmlTextView extends AppCompatTextView {

public HtmlTextView(Context context) {
    super(context);
    init();
}

private void init(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        setText(Html.fromHtml(getText().toString(), Html.FROM_HTML_MODE_COMPACT));
    } else {
        setText(Html.fromHtml(getText().toString()));
    }
 }
}

Aktualisierung der Antwort oben

Isaac Sekamatte
quelle
1

Verwenden Sie den folgenden Code, um die Lösung zu erhalten:

textView.setText(fromHtml("<Your Html Text>"))

Gebrauchsmethode

public static Spanned fromHtml(String text)
{
    Spanned result;
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        result = Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
    } else {
        result = Html.fromHtml(text);
    }
    return result;
}
Somesh Kumar
quelle
1

Erstellt Kotlin- Erweiterungen zum Konvertieren von HTML aus String -

fun String?.toHtml(): Spanned? {
    if (this.isNullOrEmpty()) return null
    return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_COMPACT)
}
römisch
quelle
0

Darf ich eine etwas hackige, aber immer noch geniale Lösung vorschlagen! Ich habe die Idee aus diesem Artikel und habe sie für Android angepasst. Grundsätzlich verwenden Sie a WebViewund fügen den HTML-Code, den Sie anzeigen und bearbeiten möchten, in ein bearbeitbares div-Tag ein. Auf diese Weise wird beim Tippen auf WebViewdie Tastatur die Tastatur angezeigt und die Bearbeitung ermöglicht. Sie fügen einfach etwas JavaScript hinzu, um das bearbeitete HTML und voila zurück zu bekommen!

Hier ist der Code:

public class HtmlTextEditor extends WebView {

    class JsObject {
        // This field always keeps the latest edited text
        public String text;
        @JavascriptInterface
        public void textDidChange(String newText) {
            text = newText.replace("\n", "");
        }
    }

    private JsObject mJsObject;

    public HtmlTextEditor(Context context, AttributeSet attrs) {
        super(context, attrs);

        getSettings().setJavaScriptEnabled(true);
        mJsObject = new JsObject();
        addJavascriptInterface(mJsObject, "injectedObject");
        setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                loadUrl(
                        "javascript:(function() { " +
                            "    var editor = document.getElementById(\"editor\");" +
                            "    editor.addEventListener(\"input\", function() {" +
                            "        injectedObject.textDidChange(editor.innerHTML);" +
                            "    }, false)" +
                            "})()");
            }
        });
    }

    public void setText(String text) {
        if (text == null) { text = ""; }

        String editableHtmlTemplate = "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta name=\"viewport\" content=\"initial-scale=1.0\" />" + "</head>" + "<body>" + "<div id=\"editor\" contenteditable=\"true\">___REPLACE___</div>" + "</body>" + "</html>";
        String editableHtml = editableHtmlTemplate.replace("___REPLACE___", text);
        loadData(editableHtml, "text/html; charset=utf-8", "UTF-8");
        // Init the text field in case it's read without editing the text before
        mJsObject.text = text;
    }

    public String getText() {
        return mJsObject.text;
    }
}

Und hier ist die Komponente als Kern.

Hinweis: Ich habe den Rückruf zur Höhenänderung von der ursprünglichen Lösung nicht benötigt, daher fehlt dieser hier, aber Sie können ihn bei Bedarf einfach hinzufügen.

AX
quelle
0

Wenn Sie androidx.in Ihrem Projekt * Klassen verwenden, sollten Sie diese verwenden HtmlCompat.fromHtml(text, flag). Quelle der Methode ist:

@NonNull public static Spanned fromHtml(@NonNull String source, @FromHtmlFlags int flags) { if (Build.VERSION.SDK_INT >= 24) { return Html.fromHtml(source, flags); } //noinspection deprecation return Html.fromHtml(source); }

Es ist besser als Html.fromHtml, da weniger Code, nur eine Zeile und die empfohlene Verwendung vorhanden sind.

Pandabear
quelle
0

Sie können die einfache Kotlin-Erweiterungsfunktion wie folgt verwenden:

fun TextView.setHtmlText(source: String) {
    this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}

Und Verwendung:

textViewMessage.setHtmlText("Message: <b>Hello World</b>")
seyfullah.bilgin
quelle
0

Verwenden Sie einfach:

String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));
Sumit Shukla
quelle