web-dev-qa-db-fra.com

Comment afficher le HTML dans TextView?

J'ai simpleHTML:

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

Je veux afficher le texte stylé HTML dans TextView. Comment faire ça?

669
UMAR

Vous devez utiliser Html.fromHtml() pour utiliser HTML dans vos chaînes XML. Référencer simplement une chaîne avec HTML dans votre mise en page XML ne fonctionnera pas.

Voici ce que vous devriez faire:

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>"));
}
1193
David Hedlund

setText (Html.fromHtml (bodyData)) est obsolète après api 24. Vous devez maintenant procéder comme suit: 

 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));
 }
66
Shohan Ahmed Sijan

Jetez un coup d'oeil sur ceci: https://stackoverflow.com/a/8558249/450148

C'est assez bon aussi !!

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

Cela ne fonctionne que pour quelques tags.

61
Felipe

Si vous voulez pouvoir le configurer via XML sans aucune modification en code Java, cette idée peut vous être utile. Vous appelez simplement init depuis le constructeur et définissez le texte au format HTML.

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"/>
38
user1299412

Le code ci-dessous a donné le meilleur résultat pour moi.

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
21
Rajiv Manivannan

Si vous essayez d'afficher du code HTML à partir d'un identifiant de ressource chaîne, la mise en forme risque de ne pas s'afficher à l'écran. Si cela vous arrive, essayez plutôt d'utiliser les balises CDATA:

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

Voir ce post pour plus de détails.

19
Phileo99

Si vous souhaitez simplement afficher du texte HTML et que vous n'avez pas vraiment besoin d'une TextView, prenez une WebView et utilisez-la comme suit:

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

Cela ne vous limite pas non plus à quelques balises HTML.

11
prom85
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());
11
Pedro

La meilleure approche pour utiliser les sections CData pour la chaîne dans le fichier strings.xml afin d’obtenir un affichage réel du contenu html dans TextView, l’extrait de code ci-dessous vous en donnera une idée juste.

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

La section CData dans le texte de la chaîne conserve les données de balise HTML intactes même après le formatage du texte à l'aide de la méthode String.format. Ainsi, Html.fromHtml (str) fonctionne bien et vous verrez le texte en gras dans le message de bienvenue.

Sortie:

Bienvenue dans votre magasin d'applications musicales préféré. Connecté en tant que: nom d'utilisateur

10
Rajendhiran Easu

Il est à noter que la méthode Html.fromHtml (String source) est obsolète à partir du niveau 24. Si c'est votre API cible, vous devez utiliser Html.fromHtml (String source, int flags) .

10
Teo Inke

Je voudrais aussi suggérer le projet suivant: https://github.com/NightWhistler/HtmlSpanner

L'utilisation est presque identique à celle du convertisseur Android par défaut:

(new HtmlSpanner()).fromHtml()

Je l'ai trouvé après avoir déjà démarré par ma propre implémentation de convertisseur html en spannable, car Html.fromHtml standard n'offre pas suffisamment de flexibilité pour le contrôle du rendu et aucune possibilité d'utiliser des polices personnalisées à partir de ttf

6
Fedotchenco Denis

Utilisation simple Html.fromHtml("html string"). Cela fonctionnera. Si la chaîne a des balises comme <h1>, alors des espaces viendront. Mais nous ne pouvons pas éliminer ces espaces. Si vous souhaitez toujours supprimer les espaces, vous pouvez supprimer les balises de la chaîne, puis la transmettre à la méthode Html.fromHtml("html string");. De plus, ces chaînes proviennent généralement du serveur (dynamique), mais pas souvent, s'il est préférable de transmettre la chaîne telle quelle à la méthode plutôt que de supprimer les balises de la chaîne.

5
java dev
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
4
samuel gildas

Faites une méthode globale comme:

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

Vous pouvez également l'utiliser dans votre activité/fragment comme:

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

J'ai implémenté cela en utilisant la vue web. Dans mon cas, je dois charger l'image à partir d'une URL avec le texte en mode texte et cela fonctionne pour moi.

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);
3
Killer

Il a été suggéré, à travers diverses réponses, d’utiliser la classe Html framework comme suggéré ici, mais malheureusement, cette classe a un comportement différent selon les versions d’Android et divers bogues non traités, comme le montrent les numéros 214637 , 14778 , 235128 et 75953 .

Par conséquent, vous souhaiterez peut-être utiliser une bibliothèque de compatibilité pour standardiser et archiver la classe HTML dans les versions Android, ce qui inclut davantage de rappels pour les éléments et le style:

Projet Github HtmlCompat

Bien que similaire à la classe HTML du framework, certaines modifications de signature ont été nécessaires pour permettre davantage de rappels. Voici l'exemple de la page GitHub:

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);
2
Paul Lammertsma

Je sais que cette question est ancienne. Autres réponses suggérant ici la méthode Html.fromHtml() . Je vous suggère d'utiliser HtmlCompat.fromHtml() from Android.support.v4.text.HtmlCompat package. Comme il s’agit d’une version rétro-compatible de la classe Html.

Exemple de code:

import Android.support.v4.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);

De cette façon, vous pouvez éviter la vérification de la version de l'API Android et sa facilité d'utilisation (solution à une seule ligne).

2
Shashanth

Lorsque vous écrivez une vue de texte personnalisée, la fonctionnalité de texte d'ensemble HTML de base sera supprimée de certains des périphériques.

Nous devons donc suivre les étapes supplémentaires suivantes: 

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}
2
Vinayak
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()));
    }
 }
}

mise à jour de réponse ci-dessus

1
Isaac Sekamatte

Puis-je suggérer une solution quelque peu hacky mais toujours géniale! J'ai eu l'idée de cet article et je l'ai adapté pour Android. En gros, vous utilisez une WebView et insérez le code HTML que vous souhaitez afficher et modifier dans une balise div éditable. Ainsi, lorsque l'utilisateur appuie sur WebView, le clavier apparaît et permet l'édition. Ils vous venez d'ajouter du JavaScript pour récupérer le code HTML édité et le tour est joué!

Voici le 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;
    }
}

Et ici est le composant en tant que Gist.

Remarque: je n'avais pas besoin du rappel de changement de hauteur de la solution d'origine; c'est donc ce qui manque ici, mais vous pouvez facilement l'ajouter si nécessaire.

0
AXE

Si vous utilisez des classes androidx. * dans votre projet, vous devez utiliser HtmlCompat.fromHtml(text, flag). La source de la méthode est:

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

C'est un meilleur moyen que Html.fromHtml car il y a moins de code, une seule ligne et la manière recommandée de l'utiliser.

0
pandabear