J'ai du HTML simple :
<h2>Title</h2><br>
<p>description here</p>
Je souhaite afficher le texte de style HTML dans celui-ci TextView
. Comment faire ça?
J'ai du HTML simple :
<h2>Title</h2><br>
<p>description here</p>
Je souhaite afficher le texte de style HTML dans celui-ci TextView
. Comment faire ça?
Réponses:
Vous devez utiliser Html.fromHtml()
pour utiliser HTML dans vos chaînes XML. Le simple fait de référencer une chaîne avec HTML dans votre mise en page XML 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>"));
}
h2
par définition crée beaucoup de marge autour de lui. et p
vient également avec une certaine marge. si vous ne voulez pas l'écart, vous voudrez peut-être envisager d'utiliser d'autres éléments html.
android.text.Html.fromHtml
. Je sais que la plupart des IDE le corrigent pour vous, mais pour plus de lisibilité, il est plus agréable de connaître les noms des packages.
setText (Html.fromHtml (bodyData)) est obsolète après l'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));
}
Jetez un oeil à ce sujet: https://stackoverflow.com/a/8558249/450148
C'est assez bien aussi !!
<resource>
<string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>
Cela ne fonctionne que pour quelques balises.
Si vous voulez pouvoir le configurer via xml sans aucune modification dans le code java, cette idée peut vous être utile. Vous appelez simplement init du constructeur et définissez le texte en 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"/>
Si vous essayez d'afficher du HTML à partir d'un ID de ressource de chaîne, le formatage peut ne pas s'afficher à l'écran. Si cela vous arrive, essayez plutôt d'utiliser des 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 cet article pour plus de détails.
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);
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 simplement afficher du texte html et que vous n'en avez pas vraiment besoin TextView
, prenez-en un WebView
et utilisez-le comme suit:
String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);
Cela ne vous limite pas non plus à quelques balises html.
layout_height="wrap_content"
. Vous devrez plutôt définir une hauteur explicite ou match_parent.
La meilleure approche pour utiliser les sections CData pour la chaîne dans le fichier strings.xml pour obtenir un affichage réel du contenu html dans TextView l'extrait de code ci-dessous vous 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 chaîne conserve les données de balise html intact même après avoir formaté le texte à l'aide de la méthode String.format. Ainsi, Html.fromHtml (str) fonctionne correctement et vous verrez le texte en gras dans le message de bienvenue.
Production:
Bienvenue dans votre magasin d'applications musicales préféré. Connecté en tant que: nom d'utilisateur
Il convient de mentionner que la méthode Html.fromHtml (String source) est obsolète à partir du niveau d'API 24. Si c'est votre API cible, vous devez utiliser Html.fromHtml (String source, int flags) à la place.
Je voudrais également suggérer le projet suivant: https://github.com/NightWhistler/HtmlSpanner
L'utilisation est presque la même que celle du convertisseur Android par défaut:
(new HtmlSpanner()).fromHtml()
Je l'ai trouvé après avoir déjà commencé par la propre implémentation du convertisseur html en spannable, car Html.fromHtml standard ne fournit pas assez de flexibilité sur le contrôle du rendu et même aucune possibilité d'utiliser des polices personnalisées à partir de ttf
Je sais que cette question est ancienne. D'autres réponses suggèrent ici la Html.fromHtml()
méthode. Je vous suggère d'utiliser à HtmlCompat.fromHtml()
partir du androidx.core.text.HtmlCompat
package. Comme il s'agit d'une version rétrocompatible deHtml
classe.
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 la vérification de la version de l'API Android et c'est facile à utiliser (solution à une seule ligne).
Utilisation simple Html.fromHtml("html string")
. Cela fonctionnera. Si la chaîne a des balises comme cela, des <h1>
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 transmettre la chaîne à la méthode Html.fromHtml("html string");
. De manière générale, ces chaînes proviennent également 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.
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Créez 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));
J'ai implémenté cela en utilisant la vue Web. Dans mon cas, je dois charger l'image de l'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);
Il a été suggéré à travers diverses réponses d'utiliser la classe de framework Html comme suggéré ici, mais malheureusement, cette classe a un comportement différent dans différentes versions d'Android et divers bogues non résolus , comme démontré dans les problèmes 214637 , 14778 , 235128 et 75953 .
Vous souhaiterez donc peut-être utiliser une bibliothèque de compatibilité pour normaliser et rétroporter la classe Html sur les versions Android, ce qui inclut davantage de rappels pour les éléments et le style:
Bien qu'elle soit similaire à la classe Html du framework, certaines modifications de signature étaient nécessaires pour autoriser plus 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);
Chaque fois que vous écrivez une vue de texte personnalisée, la fonctionnalité de base du texte HTML sera supprimée de certains appareils.
Nous devons donc suivre les étapes supplémentaires pour faire fonctionner
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 la réponse ci-dessus
Utilisez le code ci-dessous pour obtenir la solution:
textView.setText(fromHtml("<Your Html Text>"))
Méthode d'utilité
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;
}
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ée 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 appuie sur leWebView
le clavier apparaît et permet l'édition. Ils vous ajoutent juste du JavaScript pour récupérer le 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 voici le composant en tant que Gist.
Remarque: Je n'avais pas besoin du rappel de changement de hauteur de la solution d'origine, il manque donc ici, mais vous pouvez facilement l'ajouter si nécessaire.
Si vous utilisez des androidx.
classes * 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 mieux que Html.fromHtml car il y a moins de code, une seule ligne et la façon recommandée de l'utiliser.
Vous pouvez utiliser une fonction d'extension Kotlin simple comme ceci:
fun TextView.setHtmlText(source: String) {
this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
Et l'utilisation:
textViewMessage.setHtmlText("Message: <b>Hello World</b>")
Utilisez simplement:
String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));