Question

J'ai simplement HTML :

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

Je veux afficher HTML texte formaté dans TextView. Comment faire?

Était-ce utile?

La solution

Vous devez utiliser Html.fromHtml() pour utiliser le HTML dans vos chaînes XML. référençant simplement une chaîne avec HTML dans votre XML de mise en page ne fonctionnera pas.

Voici ce que vous devez 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>"));
}

Autres conseils

setText (Html.fromHtml (bodyData)) dépréciée après api 24. Maintenant, vous devez faire ceci:

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

Regardez sur ce point: https://stackoverflow.com/a/8558249/450148

Il est très bon aussi !!

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

Il ne fonctionne que pour quelques balises.

Si vous voulez être en mesure de le configurer par XML sans aucune modification dans le code Java, vous trouverez peut-être cette idée utile. Il suffit de vous appeler init du constructeur et définissez le texte comme 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"/>

Le code ci-dessous donne 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);

Si vous essayez de montrer HTML à partir d'un identifiant de ressource de chaîne, la mise en forme peut ne pas apparaître à l'écran. Si cela vous arrive, essayez d'utiliser les balises CDATA à la place:

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 cette pour afficher plus de détails.

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

Si vous voulez juste afficher un texte html et ne pas vraiment besoin d'un TextView, puis prendre un WebView et l'utiliser comme suit:

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

Cela ne vous empêche pas quelques balises html soit.

La meilleure approche à utiliser les sections CDATA pour la chaîne dans le fichier strings.xml pour obtenir un affichage réel du contenu HTML au TextView l'extrait de code ci-dessous vous donnera l'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));

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 en utilisant la méthode String.format. Ainsi, Html.fromHtml (str) fonctionne très bien et vous verrez le texte en gras dans le message de bienvenue.

Sortie:

  

Bienvenue, votre magasin préféré de l'application de la musique. Connecté en tant que: nom d'utilisateur

Il convient de mentionner que la méthode Html .fromHtml (source String) est dépréciée au niveau de l'API 24. Si tel est votre API cible, vous devez utiliser Html.fromHtml (source String, drapeaux int) à la place.

Je voudrais également proposer la suite du projet: https://github.com/NightWhistler/HtmlSpanner

L'utilisation est presque le même que le convertisseur androïde par défaut:

(new HtmlSpanner()).fromHtml()

Je l'ai trouvé après avoir déjà commencé par la mise en œuvre propre du html convertisseur spannable, car la norme Html.fromHtml ne fournit pas suffisamment de flexibilité sur le rendu de contrôle et même pas la possibilité d'utiliser des polices personnalisées à partir TTF

Utilisation simple Html.fromHtml("html string"). Cela fonctionne. Si la chaîne a des balises comme <h1> alors des espaces viendront. Mais nous ne pouvons pas éliminer ces espaces. Si vous voulez toujours supprimer les espaces, vous pouvez supprimer les balises de la chaîne, puis passer la chaîne à la méthode Html.fromHtml("html string");. De plus généralement ces chaînes proviennent de serveur (dynamique), mais pas souvent, s'il vaut mieux le cas de passer la chaîne comme il est la méthode que d'essayer de supprimer les balises de la chaîne.

String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)

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

Je l'ai mis en œuvre ce en utilisant l'affichage Web. Dans mon cas, je dois charger l'image depuis l'URL ainsi que le texte en vue du 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);

Il a été suggéré par diverses réponses à utiliser le Html classe cadre comme suggéré ici, mais malheureusement, cette classe a un comportement différent dans les différentes versions d'Android et divers bugs non adressés, comme l'a démontré dans les questions 214637 , 14778 , 235128 et 75953 .

Vous pouvez donc utiliser une bibliothèque de compatibilité pour standardiser et rétroporter la classe Html dans les versions Android qui comprend plus callbacks pour les éléments et le style:

  

projet Github HtmlCompat

Bien qu'il soit similaire à la classe Html du cadre, sont nécessaires des changements de signature pour permettre à plus callbacks. 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);

Je sais que cette question est ancienne. D'autres réponses ici suggérant Html.fromHtml() méthode. Je vous suggère d'utiliser HtmlCompat.fromHtml() du paquet androidx.core.text.HtmlCompat. Comme cela est en arrière version compatible de classe Html.

Exemple de code:

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

De cette façon, vous pouvez éviter Android vérifier la version de l'API et il est facile à utiliser (solution d'une seule ligne).

Chaque fois que vous écrivez mode texte personnalisé fonction de base de texte HTML jeu sera se forme a disparu quelques-uns des appareils.

Nous devons donc faire en suivant les étapes addtional font est un travail

public class CustomTextView extends TextView {

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

Puis-je suggérer une solution un peu hacky mais toujours le génie! J'ai eu l'idée de cet article et adaptèrent Pour Android. Fondamentalement, vous utilisez un WebView et insérez le code HTML que vous souhaitez afficher et modifier dans une balise div modifiable. De cette façon, lorsque l'utilisateur tape le WebView le clavier apparaît et permet d'éditer. Ils vous suffit d'ajouter un peu de JavaScript pour récupérer le code HTML et le tour est joué édité!

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

est le composant en tant Gist.

Note: Je ne l'ai pas besoin du rappel de changement de hauteur de la solution initiale pour ce qui manque ici, mais vous pouvez facilement ajouter si nécessaire

.

Si vous utilisez des classes de androidx. de * dans votre projet, vous devez utiliser HtmlCompat.fromHtml(text, flag). 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); }

Il est mieux que Html.fromHtml car il y a moins de code, une seule ligne, et a recommandé façon de l'utiliser.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top