J'ai simpleHTML:
<h2>Title</h2><br>
<p>description here</p>
Je veux afficher le texte stylé HTML dans TextView
. Comment faire ça?
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>"));
}
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));
}
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.
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"/>
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);
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.
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.
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());
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
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) .
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
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.
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
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));
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);
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:
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);
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).
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()));
}
}
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 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.
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.