如何在TextView中显示HTML?

How to display HTML in TextView?

提问人: 提问时间:1/22/2010 最后编辑:9 revs, 7 users 35%UMAR 更新时间:12/22/2022 访问量:823257

问:

我有简单的HTML

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

我想在 .如何做到这一点?TextView

Android HTML XML 解析 textview

评论

8赞 DerMike 1/22/2010
是要显示标签还是省略标签?
1赞 Nilanchala 4/8/2013
查看此链接以获取工作示例 javatechig.com/2013/04/07/how-to-display-html-in-android-view
1赞 crgarridos 8/1/2016
如果您正在寻找已弃用的解决方案,它就在这里 stackoverflow.com/questions/37904739/......
0赞 CleanCoder 7/3/2020
textview.setText(Html.fromHtml(“你的HTML”));是仅显示 HTML 标记的最佳方法。还有一种玩JS的方法。
0赞 abdul rehman 2/20/2021
Android 不支持所有 HTML 标记。查看此 arkapp.medium.com/android-set-html-in-text-view-b912e1a96b21 以更好地了解如何在文本视图中使用。

答:

1576赞 5 revs, 5 users 28%Boken #1

您需要使用 Html.fromHtml() 在 XML 字符串中使用 HTML。在布局 XML 中简单地引用带有 HTML 的字符串是行不通的。

这是你应该在 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>"));
}

在 Kotlin 中:

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

评论

9赞 David Hedlund 1/22/2010
h2根据定义,它本身会产生很多利润。并且还带有一些余量。如果您不想要 GAP,您可能需要考虑使用其他 HTML 元素。p
11赞 Gerard 4/29/2012
Kostadin,你可以把标签放在XML中,你只需要把它们包装在CDATA括号里。
3赞 Bitcoin Cash - ADA enthusiast 8/26/2013
对于那些希望它与 ol/ul/li 标签一起工作的人,请查看此解决方案: stackoverflow.com/a/3150456/1369016
14赞 Martin 10/22/2013
那应该是.我知道大多数IDE会为您修复它,但为了可读性,最好知道软件包名称。android.text.Html.fromHtml
14赞 Joffrey 6/19/2014
@Martin我不会说可读性,而是详尽无遗。在此类代码中直接使用的 IMO 完全限定名称的可读性低于短名称。但我同意你的观点,即这样的答案应该提供一揽子计划(在旁注中),这里的链接要点;)
74赞 5 revs, 2 users 78%Felipe Micaroni Lalli #2

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

也挺不错的!!

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

它仅适用于少数标签。

评论

13赞 mente 2/11/2014
此方法是否支持任何标记列表?
26赞 JerabekJakub 7/18/2014
@mente 根据源代码:<a>、<b>、<big>、<blockquote>、<br>、<cite>、<dfn> <div align=“...”>、<em>、<font size=“...”color=“...”face=“...”> <h1-6>, <i>, <img src=“...”>, <p>, <small> <strike>, <strong>, <sub>, <sup>, <tt>, <u> (来源: dzone.com/snippets/how-display-html-android)
0赞 MiguelHincapieC 4/28/2015
@JerabekJakub但要小心,如果你要处理img,你必须实现Html.ImageGetter。
0赞 Joh 1/29/2016
@0mahc0当实现 img 时,是否可以设置大小?
1赞 MiguelHincapieC 2/3/2016
@Joh是的,这是可能的。当您实现 .ImageGetter,有一个名为 getDrawable(String source) 的方法。如果您需要更多帮助,请创建一个问题并标记我,我将为您提供一个示例;)
5赞 3 revs, 3 users 50%nole #3

简单易用。这将起作用。如果字符串有这样的标签,那么空格就会出现。但我们不能消除这些空间。如果仍要删除空格,则可以删除字符串中的标签,然后将字符串传递给方法。此外,通常这些字符串来自 server(dynamic),但并不常见,如果是这种情况,最好将字符串按原样传递给方法,而不是尝试从字符串中删除标签。Html.fromHtml("html string")<h1>Html.fromHtml("html string");

27赞 4 revs, 3 users 61%Rajiv Manivannan #4

下面的代码为我提供了最好的结果。

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
14赞 Pedro #5
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());

评论

0赞 EdmundYeung99 12/2/2014
如何更改锚点的颜色?
0赞 Pedro 12/3/2014
android:textColorLink=“颜色”
0赞 EdmundYeung99 12/3/2014
这会将整个 textview 着色为红色,但如果我只想要锚标记,我需要用 <font> 标签包装 <a> 标签并在其中添加颜色
46赞 4 revs, 2 users 98%user1299412 #6

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

评论

2赞 GilbertS 1/29/2020
什么是“...”。请澄清
0赞 Amit Kumar 7/17/2020
这是更通用和干净的解决方案
1赞 shahrukhamd 9/14/2021
更简单的方法是创建一个绑定适配器,不是吗?@BindingAdapter(value = [“htmlText”]) fun TextView.setHtmlText(string: String?){ text = HtmlCompat.fromHtml(string?:“”, HtmlCompat.FROM_HTML_MODE_COMPACT) }
6赞 Fedotchenco Denis #7

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

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

(new HtmlSpanner()).fromHtml()

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

评论

0赞 Araju 8/18/2017
我收到以下错误:错误:(80, 13) 无法解决:com.osbcp.cssparser:cssparser:1.5 如何解决此问题?
13赞 prom85 #8

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

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

这也不会将您限制为几个 html 标签。

评论

3赞 Ridcully 10/9/2016
虽然这是绕过 TextView 支持的受限制的 html 标记集的一种非常有用的方法,但它的缺点是它不能很好地与 .您必须设置明确的高度或match_parent。layout_height="wrap_content"
5赞 Jackky777 2/26/2017
WebView 速度很慢
4赞 Shubham AgaRwal #9

我已经使用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);

评论

0赞 shawkinaw 1/9/2016
为了正确显示 UTF-8,您需要将 MIME 类型设置为“text/html;字符集=UTF-8”。
4赞 2 revs, 2 users 50%samuel gildas #10
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
10赞 Teo Inke #11

值得一提的是,自 API 级别 24 起,Html.fromHtml(String source) 方法已弃用。如果这是您的目标 API,则应改用 Html.fromHtml(String source, int flags)。

39赞 2 revsPhileo99 #12

如果您尝试从字符串资源 ID 显示 HTML,则格式可能不会显示在屏幕上。如果您遇到这种情况,请尝试改用 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));

有关详细信息,请参阅此帖子

评论

1赞 XMAN 3/20/2017
谢谢,这为我做到了 - 使用 API 23。
12赞 2 revs, 2 users 97%Rajendhiran Easu #13

将 CData 部分用于字符串 .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 code
String welcomStr=String.format(getString(R.string.welcome_text),username);
tvWelcomeUser.setText(Html.fromHtml(welcomStr));

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

输出:

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

评论

0赞 XMAN 3/20/2017
谢谢,这为我做到了 - 使用 API 23。
0赞 AndroidGuy 4/13/2017
谢谢,你救了我的一天:)只是一个小小的补充:我们需要在上面的代码中添加这个检查:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES。N) { // 对于 24 个及更多 api textView.setText(Html.fromHtml(welcomStr, Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else { // 对于较旧的 api textView.setText(Html.fromHtml(welcomStr)); } .API>=24 的第二个参数标志的值可以是任何值。
89赞 Shohan Ahmed Sijan #14

setText(Html.fromHtml(bodyData)) 在 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));
 }

评论

5赞 galcyurio 5/24/2019
为什么在 API 24+ 中使用 FROM_HTML_MODE_LEGACY?
0赞 abdul rehman 2/20/2021
这对我有很大帮助。但仍然不是所有标签都支持 arkapp.medium.com/android-set-html-in-text-view-b912e1a96b21
6赞 2 revs, 2 users 87%Paul Lammertsma #15

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

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

Github 项目 HtmlCompat

虽然它类似于框架的 Html 类,但需要进行一些签名更改才能允许更多回调。下面是 GitHub 页面中的示例:Here's the sample from the GitHub page:

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

评论

0赞 Paul Lammertsma 3/15/2017
@MartijnPieters 先前封闭的答案与这个问题的答案重复,涉及弃用框架方法。我已经扩展了使用兼容性库将是一种更好的方法的原因。我认为将任何一个问题标记为彼此重复是不合理的,因为它们明显不同。
2赞 2 revs, 2 users 77%Vinayak #16

每当您编写自定义文本视图时,基本的 HTML 设置文本功能都会从某些设备中消失。

因此,我们需要执行以下附加步骤,使工作成为工作

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}
4赞 Shailendra Madda #17

创建一个全局方法,如下所示:

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

您也可以在 Activity/Fragment 中使用它,例如:

text_view.setText(stripHtml(htmlText));
0赞 2 revsAXE #18

我可以建议一个有点骇人喜欢但仍然很天才的解决方案!我从这篇文章中得到了这个想法,并将其改编为 Android。基本上,你使用一个并插入你想在可编辑的div标签中显示和编辑的HTML。这样,当用户点击键盘时,将出现并允许编辑。他们只需添加一些 JavaScript 即可取回编辑后的 HTML,瞧!WebViewWebView

代码如下:

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

这是作为 Gist 的组件。

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

30赞 2 revs, 2 users 94%Shashanth #19

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

示例代码:

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 版本检查,并且易于使用(单行解决方案)。

评论

0赞 user1209216 1/28/2019
这与旧的methot有何不同?html模式的用途是什么?
4赞 Subhrajyoti Sen 1/30/2019
正在寻找这样的东西。谢谢:)
3赞 Shuhratjon Jumaev 8/21/2020
我特意登录了你的答案。每个人都应该使用的东西。谢谢。
1赞 dicarlomagnus 3/16/2022
这是最好的答案!谢谢!
5赞 2 revspandabear #20

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

该方法的来源是:

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

它比代码较少时更好 - 只有一行代码,建议使用它。HtmlCompat.fromHtmlHtml.fromHtml

评论

0赞 Kishan Solanki 6/13/2023
应该在标志中传递什么?
1赞 Isaac Sekamatte #21
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()));
    }
 }
}

更新上述答案

1赞 2 revs, 2 users 67%Somesh Kumar #22

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

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

Utitilty 方法

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;
}
1赞 seyfullah.bilgin #23

您可以使用简单的 Kotlin 扩展函数,如下所示:

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

和用法:

textViewMessage.setHtmlText("Message: <b>Hello World</b>")
2赞 2 revsSumit Shukla #24

只需使用:

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

创建了 Kotlin 扩展来转换 html 来自 String -

fun String?.toHtml(): Spanned? {
    if (this.isNullOrEmpty()) return null
    return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_COMPACT)
}
5赞 Sandeep Pareek #26

简单使用 enter image description here

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>")
2赞 shahrukhamd #27

人们建议为 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>"
   ... />
-1赞 Jared Rummler #28

您可以使用 Github 上的 HtmlDsl 库为 Android 构建有效的 HTML:https://github.com/jaredrummler/HtmlDslTextView

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

创建一些 HTML 示例:

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

Android 支持的 HTML 元素:TextView

<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>
0赞 Dan Alboteanu #29

使用 BindingAdapter:

@BindingAdapter("renderHtml")
fun bindRenderHtml(view: TextView, description: String?) {
if (description != null) {
    view.text = HtmlCompat.fromHtml(description, FROM_HTML_MODE_COMPACT)
    view.movementMethod = LinkMovementMethod.getInstance()
} else {
    view.text = ""
}

}

用法:

  <TextView
        android:id="@+id/content_text_view"
        app:renderHtml="@{show.description}"
        ...