如何在TextView中显示超文本标记语言?

简单的超文本标记语言

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

我想在TextView中显示超文本标记语言样式的文本。如何做到这一点?

793450 次浏览

您需要使用Html.fromHtml()在XML字符串中使用超文本标记语言。在布局XML中简单地引用具有超文本标记语言的字符串是行不通的。

这是你在Java应该做的

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

静态编程语言:

textView.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {Html.fromHtml(html, Html.FROM_HTML_MODE_COMPACT)} else {Html.fromHtml(html)}

看看这个:https://stackoverflow.com/a/8558249/450148

也挺不错的!!!

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

它只适用于少数标签。

简单使用Html.fromHtml("html string")。这将起作用。如果字符串有<h1>这样的标签,那么空格就会出现。但是我们不能消除这些空格。如果您仍然想删除空格,那么您可以删除字符串中的标签,然后将字符串传递给方法Html.fromHtml("html string");。通常这些字符串来自服务器(动态),但不经常,如果是这样,最好将字符串原样传递给方法,而不是尝试从字符串中删除标签。

下面的代码给我最好的结果。

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

如果您希望能够通过xml配置它而无需对java代码进行任何修改,您可能会发现这个想法很有帮助。只需从构造函数调用init并将文本设置为html

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

xml:

<com.package.HTMLTextViewandroid:text="@string/about_item_1"/>

我还想建议以下项目:https://github.com/NightWhistler/HtmlSpanner

用法几乎与默认的Android转换器相同:

(new HtmlSpanner()).fromHtml()

在我已经开始自己实现html到可扩展转换器之后找到了它,因为标准Html.fromHtml在渲染控制方面没有提供足够的灵活性,甚至没有可能从ttf使用自定义字体

如果你只是想显示一些html文本,而不需要TextView,那么取一个WebView并像下面这样使用它:

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

这也不限制您使用一些html标签。

我已经使用Web视图实现了这一点。在我的情况下,我必须从URL加载图像以及文本视图中的文本,这对我有用。

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);
String value = html value ....mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)

值得一提的是,方法Html.fromHtml(字符串源)在API级别24时已被弃用。如果这是您的目标API,您应该改用Html.fromHtml(字符串源,int标志)

如果您尝试从字符串资源id显示超文本标记语言,格式可能不会显示在屏幕上。如果您遇到这种情况,请尝试使用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));

请参阅此帖子以了解更多详细信息。

使用CData部分作为文件中字符串strings.xml最佳方法是将html内容实际显示到TextView下面的代码片段将为您提供公平的想法。

//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 codeString welcomStr=String.format(getString(R.string.welcome_text),username);tvWelcomeUser.setText(Html.fromHtml(welcomStr));

字符串文本中的CData部分即使在使用String.format方法格式化文本后也保持html标记数据不变。因此,Html.fromHtml(str)工作正常,您将在欢迎消息中看到粗体文本。

输出:

欢迎来到您最喜欢的音乐应用商店。登录方式:用户名

setText(Html.fromHtml(body Data))是api 24之后的已弃用。现在你必须这样做:

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

通过各种答案建议使用Html框架类,但不幸的是,这个类在不同版本的Android和各种未解决的错误中具有不同的行为,如问题2146371477823512875953所示。

因此,您可能希望使用兼容性库来标准化和反向移植Html类跨Android版本,其中包括更多元素和样式的回调:

Github项目HtmlCompat

虽然它类似于框架的Html类,但需要一些签名更改才能允许更多回调。这是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);

每当您编写自定义文本视图时,基本的超文本标记语言集文本功能将从某些设备中消失。

所以我们需要做下面的附加步骤

public class CustomTextView extends TextView {
public CustomTextView(..) {// other instructionssetText(Html.fromHtml(getText().toString()));}}

创建一个全局方法,例如:

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

你也可以在你的活动/片段中使用它,比如:

text_view.setText(stripHtml(htmlText));

我可以建议一个有点hacky但仍然天才的解决方案!我从这篇文章得到了这个想法,并将其改编为Android。基本上,你使用WebView并在可编辑的div标签中插入你想要显示和编辑的超文本标记语言。这样,当用户点击WebView时,键盘就会出现并允许编辑。他们只需添加一些JavaScript来恢复编辑过的超文本标记语言,瞧!

以下是代码:

public class HtmlTextEditor extends WebView {
class JsObject {// This field always keeps the latest edited textpublic String text;@JavascriptInterfacepublic 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(){@Overridepublic 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 beforemJsObject.text = text;}
public String getText() {return mJsObject.text;}}

这里是作为Gist的组件。

注意:我不需要原始解决方案中的高度更改回调,因此此处缺少,但如果需要,您可以轻松添加它。

我知道这个问题很老。这里的其他答案建议Html.fromHtml()方法。我建议您使用androidx.core.text.HtmlCompat包中的HtmlCompat.fromHtml()。因为这是Html类的向下兼容版本。

示例代码:

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

通过这种方式,您可以避免Android API版本检查,并且易于使用(单行解决方案)。

如果你在项目中使用androidx.*类,你应该使用HtmlCompat.fromHtml(text, flag)

该方法的来源是:

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

最好使用HtmlCompat.fromHtml而不是Html.fromHtml,因为代码较少-只有一行代码,并且推荐使用它。

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

更新上面的答案

使用以下代码获取解决方案:

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

实用方法

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

您可以使用简单的静态编程语言扩展函数,如下所示:

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

及用法:

textViewMessage.setHtmlText("Message: <b>Hello World</b>")

只需使用:

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

创建静态编程语言扩展以将htmlString转换-

fun String?.toHtml(): Spanned? {if (this.isNullOrEmpty()) return nullreturn HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_COMPACT)}

简单的使用输入图片描述

checkBoxTextView.text =Html.fromHtml("<p><font color=#666666>I agree to</font><font color=#0173B7>  <b><u>Terms & Conditions</u></b></font><font color=#666666> and the <u></font><b><font color=#0173B7>Privacy Policy</font></u></b></font></p>")

人们提出了TextView、WebView和各种解决方案的子类。我想知道为什么没有人提到一个简单的绑定适配器

@BindingAdapter(value = ["htmlText"])fun TextView.setHtmlText(string: String?) {text = HtmlCompat.fromHtml(string?:"", HtmlCompat.FROM_HTML_MODE_COMPACT)}

所以你的TextView xml看起来像

<TextView...htmlText="<p>Your <b>HTML</b> text</p>"... />

您可以使用Github上的HtmlDsl库为AndroidTextView构建有效的超文本标记语言:https://github.com/jaredrummler/HtmlDsl

该库提供了语法糖,通过仅支持Android呈现的元素和属性,使代码更易于理解且不易出错。

创建一些超文本标记语言的示例:

textView.setHtml {h3("Android Versions:")ul {li {a(href = "https://developer.android.com/about/versions/12/get") {+"Android 12 Beta"}}li("Android 11")li("Android 10")li("Pie")li("Oreo")li("Nougat")li("Marshmallow")li("Lollipop")// ...}
small {sub {+"by "a {href = "https://github.com/jaredrummler"text = "Jared Rummler"}}}}

AndroidTextView支持的超文本标记语言元素:

<a href="..."><b><big><blockquote><br><cite><dfn><div align="..."><em><font color="..." face="..."><h1><h2><h3><h4><h5><h6><i><img src="..."><p><small><strike><strong><sub><sup><tt><u><ul><li>