如何在TextView中显示HTML?

时间:2010-01-22 09:14:22

标签: android html xml-parsing textview

我有简单的 HTML

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

我想在TextView中显示HTML样式的文本。怎么做?

26 个答案:

答案 0 :(得分:1230)

您需要使用Html.fromHtml()在XML字符串中使用HTML。只需在布局XML中引用带有HTML的String就行了。

这是你应该做的:

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

答案 1 :(得分:67)

api 24之后

setText(Html.fromHtml(bodyData)) 已弃用。现在你必须这样做:

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

答案 2 :(得分:61)

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

这也很不错!!

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

仅适用于少量标签。

答案 3 :(得分:40)

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

答案 4 :(得分:22)

以下代码为我提供了最佳结果。

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

答案 5 :(得分:19)

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

答案 6 :(得分:12)

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

答案 7 :(得分:11)

如果你只是想显示一些html文字并且不需要TextView,那么请选择WebView并使用它如下:

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

这也不会限制你使用几个html标签。

答案 8 :(得分:10)

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

答案 9 :(得分:10)

对strings.xml文件中的字符串使用CData部分以获取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)工作正常,您将在欢迎消息中看到粗体文本。

<强>输出:

  

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

答案 10 :(得分:6)

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

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

(new HtmlSpanner()).fromHtml()

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

答案 11 :(得分:5)

简单使用Html.fromHtml("html string")。这会奏效。如果字符串包含<h1>之类的标签,则会出现空格。但我们无法消除这些空间。如果您仍想删除空格,则可以删除字符串中的标记,然后将字符串传递给方法Html.fromHtml("html string");。通常这些字符串来自服务器(动态),但不常见,如果最好将字符串传递给方法,而不是尝试从字符串中删除标记。

答案 12 :(得分:5)

创建了 Kotlin 扩展程序以将 html 字符串-

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

答案 13 :(得分:4)

String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)

答案 14 :(得分:4)

采用如下全局方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = DB::table('users')->where('money', 100)->first();
        return view('home')->with('users', $users);
        $users->save();
    }
}

您还可以在活动/片段中使用它,例如:

<div class="col-xs">
    <div class="amountOfMoney">{{$users->money}}</div>
</div>

答案 15 :(得分:3)

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

答案 16 :(得分:3)

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

答案 17 :(得分:2)

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

因此,您可能希望使用兼容性库来标准化和反向移植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);

答案 18 :(得分:2)

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

因此我们需要执行以下其他步骤,使之正常工作

public class CustomTextView extends TextView {

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

答案 19 :(得分:1)

只需使用:

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

答案 20 :(得分:0)

我可以建议一个有点怪异但仍然很聪明的解决方案!我从this article那里得到了这个想法,并将其改编为Android。基本上,您使用WebView,然后将要显示和编辑的HTML插入可编辑的div标签中。这样,当用户点击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是要点的组成部分。

注意:我不需要原始解决方案中的高度变化回调,因此这里没有,但是您可以根据需要轻松添加它。

答案 21 :(得分:0)

如果在项目中使用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); }

与Html.fromHtml相比,这是一种更好的方法,因为它的代码更少,只有一行,并且是推荐的使用方式。

答案 22 :(得分:0)

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

答案 23 :(得分:0)

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

textView.setText(fromHtml(“”))“公共静态Span fromHtml(String text){Spanned result; if(Build.VERSION.SDK_INT> = android.os.Build.VERSION_CODES.N){结果= HTML。 fromHtml(text,Html.FROM_HTML_MODE_LEGACY);} else {result = Html.fromHtml(text);}返回结果;}“

答案 24 :(得分:0)

您可以像这样使用简单的Kotlin扩展功能:

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

和用法:

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

答案 25 :(得分:0)

简单使用 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>")