【问题标题】:How to display HTML in TextView?如何在 TextView 中显示 HTML?
【发布时间】:2011-01-08 03:20:34
【问题描述】:

我有简单的HTML

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

我想在TextView 中显示 HTML 样式的文本。如何做到这一点?

【问题讨论】:

标签: android html xml-parsing textview


【解决方案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)
}

【讨论】:

  • h2 根据定义会在其自身周围创建大量边距。和p 也有一些余量。如果你不想要这个差距,你可能需要考虑使用其他 html 元素。
  • Kostadin,您可以在 XML 中放置标签,您只需将它们包装在 CDATA 括号中。
  • 对于那些希望它与 ol/ul/li 标签一起使用的人,请查看此解决方案:stackoverflow.com/a/3150456/1369016
  • 应该是android.text.Html.fromHtml。我知道大多数 IDE 会为您修复它,但为了便于阅读,最好知道包名称。
  • @Martin 我不会说为了可读性,而是说为了详尽。在这样的代码中直接使用的 IMO 完全限定名称比短名称可读性差。但我同意你的观点,这样的答案应该提供包(附注),这里的链接点;)
【解决方案2】:

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

【讨论】:

【解决方案3】:

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

也不错!!

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

它只适用于少数标签。

【讨论】:

【解决方案4】:

如果您希望能够通过 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"/>

【讨论】:

  • 什么是'...'。请澄清
  • 这是更通用和更干净的解决方案
  • 创建一个绑定适配器会更简单,不是吗? @BindingAdapter(value = ["htmlText"]) fun TextView.setHtmlText(string: String?) { text = HtmlCompat.fromHtml(string?:"", HtmlCompat.FROM_HTML_MODE_COMPACT) }
【解决方案5】:

如果您尝试从字符串资源 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));

查看post了解更多详情。

【讨论】:

  • 谢谢,这是使用 API 23 为我完成的。
【解决方案6】:

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

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);

【讨论】:

    【解决方案7】:

    我知道这个问题很老了。这里的其他答案建议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版本检查,并且易于使用(单行解决方案)。

    【讨论】:

    • 这与旧方法有何不同? html模式的目的是什么?
    • 正在寻找这样的东西。谢谢:)
    • 我特地登录来支持你的回答。那是每个人都应该使用的。谢谢。
    【解决方案8】:
    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());
    

    【讨论】:

    • 如何改变锚的颜色?
    • android:textColorLink="color"
    • 这会将整个textview着色为红色,但如果我只想要锚标签,我需要用标签包装标签并在那里添加颜色
    【解决方案9】:

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

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

    这也不限制您使用几个 html 标记。

    【讨论】:

    • 虽然这是绕过受 TextView 支持的受限 html 标签集的一种非常有用的方法,但它的缺点是 不能很好地工作 layout_height="wrap_content" .您将不得不设置一个明确的高度或 match_parent。
    • webview 很慢
    【解决方案10】:

    在 strings.xml 文件中为字符串使用 CData 部分以获得将 html 内容实际显示到 TextView 的最佳方法,下面的代码 sn-p 将为您提供公平的想法。

    //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) 工作正常,您会在欢迎消息中看到粗体文本。

    输出:

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

    【讨论】:

    • 谢谢,这是使用 API 23 为我完成的。
    • 谢谢,你拯救了我的一天 :) 只是一个小补充:我们需要在上面的代码中添加这个检查: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // for 24 api 和更多 textView.setText(Html.fromHtml(welcomStr, Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else { // 或者对于旧的 api textView.setText(Html.fromHtml(welcomStr)); } 。 API>=24 的第二个参数标志的值,可以根据需要为任何值。
    【解决方案11】:

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

    【讨论】:

      【解决方案12】:

      创建了 Kotlin 扩展来将 htmlString -

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

      【讨论】:

        【解决方案13】:

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

        用法和默认的android转换器差不多:

        (new HtmlSpanner()).fromHtml()
        

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

        【讨论】:

        • 我收到以下错误:Error:(80, 13) Failed to resolve: com.osbcp.cssparser:cssparser:1.5 我该如何解决这个问题?
        【解决方案14】:

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

        【讨论】:

          【解决方案15】:

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

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

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

          【讨论】:

          【解决方案16】:

          如果您在项目中使用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.fromHtml 比使用Html.fromHtml 更好,因为代码更少——只有一行代码,推荐使用它。

          【讨论】:

            【解决方案17】:

            我已经使用网络视图实现了这一点。在我的情况下,我必须从 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);
            

            【讨论】:

            • 为了正确显示 UTF-8,您需要将 MIME 类型设置为“text/html; charset=UTF-8”。
            【解决方案18】:
            String value = html value ....
            mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
            

            【讨论】:

              【解决方案19】:

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

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

              【讨论】:

                【解决方案20】:

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

                所以我们需要做以下额外的步骤使工作正常

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

                【讨论】:

                  【解决方案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()));
                      }
                   }
                  }
                  

                  answer above的更新

                  【讨论】:

                    【解决方案22】:

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

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

                    【讨论】:

                      【解决方案23】:

                      简单使用:

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

                      【讨论】:

                        【解决方案24】:

                        只需使用

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

                        【讨论】:

                          【解决方案25】:

                          人们已经建议了 TextView、WebView 和各种解决方案的子类。我想知道为什么没有人提到一个简单的binding adapter

                          @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>"
                             ... />
                          

                          【讨论】:

                            【解决方案26】:

                            我可以建议一个有点老套但仍然是天才的解决方案!我从this article 那里得到了这个想法,并将其改编为 Android。基本上,您使用WebView 并在可编辑的 div 标记中插入要显示和编辑的 HTML。这样,当用户点击WebView 时,键盘就会出现并允许编辑。他们只需添加一些 JavaScript 即可取回编辑后的 ​​HTML,瞧!

                            代码如下:

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

                            here 是作为 Gist 的组件。

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

                            【讨论】:

                              【解决方案27】:

                              你可以像这样使用简单的 Kotlin 扩展函数:

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

                              及用法:

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

                              【讨论】:

                                【解决方案28】:

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

                                该库提供语法糖,通过仅支持由 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>
                                

                                【讨论】:

                                  猜你喜欢
                                  相关资源
                                  最近更新 更多
                                  热门标签