从 XML 中的 html 格式的字符串资源设置 TextView 文本

Posted

技术标签:

【中文标题】从 XML 中的 html 格式的字符串资源设置 TextView 文本【英文标题】:Set TextView text from html-formatted string resource in XML 【发布时间】:2011-03-15 04:32:56 【问题描述】:

我的strings.xml 中有一些固定字符串,例如:

<resources>
    <string name="somestring">
        <B>Title</B><BR/>
        Content
    </string>
</resources>

在我的布局中,我有一个 TextView,我想用 html 格式的字符串填充它。

<TextView android:id="@+id/formattedtext"
android:layout_
android:layout_
android:text="@string/htmlstring"/>

如果我这样做,formattedtext 的内容就是 somestring 的内容,去掉了任何 html 标签,因此没有格式化。

我知道可以使用

以编程方式设置格式化文本

.setText(Html.fromHtml(somestring));

因为我在程序的其他部分使用它,它按预期工作。

要调用这个函数,我需要一个Activity,但目前我的布局只是一个简单的或多或少是纯 XML 的静态视图,我宁愿保持这种状态,以节省我的开销创建一个Activity 只是为了设置一些文本。

我是否忽略了一些明显的东西?根本不可能吗?欢迎任何帮助或解决方法!

编辑:刚刚尝试了一些东西,似乎 xml 中的 HTML 格式有一些限制:

标签必须小写

here 中提到的某些标签不起作用,例如&lt;br/&gt;(可以改用\n

【问题讨论】:

现在我知道很久了,但是我能够使用 而不是 \n 使用 html 作为 TextView 的新行。 这可以仅从 xml 工作吗?我对答案有一点赏金。在这一点上,我已经围绕它进行了编码,我认为不作为事实答案。 我觉得有趣的是没有人真正回答这个问题。 OP 声明他知道如何使用 fromHtml(),但想直接在布局文件中进行(尽管原因并不好......如果你正在绘制,你总是有一个活动/上下文可用屏幕)。也没有一个答案深入到锚标签的影响。 【参考方案1】:

以防万一有人发现这一点,有一个更好的替代方案没有记录(我在搜索了几个小时后绊倒了它,最后在 Android SDK 本身的错误列表中找到了它)。您可以在 strings.xml 中包含原始 HTML,只要您将其包装在

<![CDATA[ ...raw html... ]]>

边缘案例:

如果您希望撇号 (')、双引号 (") 和 & 号 (&) 等字符出现在呈现的文本 AS 本身中,则只需要对其进行转义,但它们可以被合理地解释为 HTML。 '" 可以表示为\'\",或者&amp;apos;&amp;quot;&amp;lt;&amp;gt; 总是 需要转义为 &amp;lt;&amp;gt; 如果您真的希望它们在文本中呈现为“”。 与号 (&) 有点复杂。 & 后跟空格会呈现为 &。 & 后跟一个或多个不构成有效 HTML 实体代码的字符呈现为 & 后跟这些字符。所以...&amp;qqq; 呈现为 &amp;qqq;,但 &amp;lt;1 呈现为 &lt;1

例子:

<string name="nice_html">
<![CDATA[
<p>This is a html-formatted \"string\" with <b>bold</b> and <i>italic</i> text</p>
<p>This is another paragraph from the same \'string\'.</p>
<p>To be clear, 0 &lt; 1, & 10 &gt; 1<p>
]]>
</string>

然后,在您的代码中:

TextView foo = (TextView)findViewById(R.id.foo);
foo.setText(Html.fromHtml(getString(R.string.nice_html), FROM_HTML_MODE_LEGACY));

恕我直言,使用起来要好几个数量级:-)


2021 年 8 月更新:我的原始答案使用了 Html.fromHtml(String),它在 API 24 中已被弃用。建议使用替代 fromHtml(String,int) 形式作为其替代。

FROM_HTML_MODE_LEGACY 可能会起作用...但其他标志之一可能是您想要做的更好的选择。

最后一点,如果您希望使用 Markdown 语法而不是 HTML 来呈现适合在 TextView 中使用的 Android Spanned 文本,现在有多个第三方库可以轻松实现,包括 @ 987654322@.

【讨论】:

只是补充一下,您还可以在 CDATA 块内使用反斜杠转义撇号/单引号,这样您就可以使用 can\'t 之类的东西,而不是无限地-丑的不能 这还能用吗?我刚试了一下,它确实显示了

@PeriHartman 你也做了Html.fromHtml(getString(R.string.nice_html)) 位吗? :) TextView foo = (TextView)findViewById(R.id.foo); foo.setText(Html.fromHtml(getString(R.string.nice_html)));需要去吗? 有没有办法避免“Html.fromHtml”?【参考方案2】:

由于这里的最佳答案暗示了一些错误(或至少太复杂),我觉得这应该更新,尽管这个问题已经很老了:

在 Android 中使用字符串资源时,您只需从 Java 代码中调用 getString(...) 或在布局 XML 中使用 android:text="@string/..."

即使你想在你的字符串中使用 HTML 标记,你也不必做很多改变:

您需要在字符串资源中转义的唯一字符是:

双引号:"变成\" 单引号:'变成\' & 符号:&amp;amp; 变为 &amp;#38;&amp;amp;

这意味着您可以添加 HTML 标记而不转义标签:

<string name="my_string"><b>Hello World!</b> This is an example.</string>

但是,可以肯定的是,您应该只使用文档中列出的 &lt;b&gt;&lt;i&gt;&lt;u&gt;

如果您想使用 来自 XML 的 HTML 字符串,请继续使用 android:text="@string/...",它将正常工作。

唯一的区别是,如果你想使用 来自 Java 代码的 HTML 字符串,你现在必须使用 getText(...) 而不是 getString(...),因为前者保留了样式和后者只会将其剥离。

就这么简单。没有 CDATA,没有 Html.fromHtml(...)

如果您确实在 HTML 标记中编码您的特殊字符,您将只需要Html.fromHtml(...)。然后将其与getString(...) 一起使用。如果您想将字符串传递给String.format(...),这可能是必要的。

in the docs 也描述了这一切。

编辑:

getText(...) 与未转义的 HTML(正如我建议的那样)或 CDATA 部分和 Html.fromHtml(...) 之间没有区别。

请参见下图进行比较:

【讨论】:

我的正在剥离它。我正在使用以下代码:getResources().getText(R.string.codename) 为了更好地提供帮助,我需要查看 Java/XML 摘录。但正如我所写:你只能确定你是否使用&lt;b&gt;&lt;i&gt;&lt;u&gt;。并不总是支持其他标签。 您的答案有效且简单。只需将带有所需 html 标记的字符串放入 strings.xml 中,然后从您的布局 xml 文件中引用它。我使用了 标签。 Yours 是另一种解决方案,而不是另一种解决方案,因为它不支持所有标签,就像另一个一样。当另一个非常简单时,我看不到这个解决方案有任何优势。 我在使用“CDATA”时遇到了问题,例如: 有 22 个字母,html 部分有 10 个。因此,如果您使用 HTML.fromhtml(getstring(...)) 您的文本将正确显示,但文本的内容需要 22 个字母空格。我在 listview 中使用并看到杂草空间。所以 gettext() 更好。【参考方案3】:

转义 HTML 标签 ...

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>

【讨论】:

这就是文档所说的:developer.android.com/intl/zh-TW/guide/topics/resources/…,但这足以让TextView 显示 HTML 吗? 这个我已经测试过了,如果你从java源代码中使用它就可以了。但是,如果您直接从布局 XML 关联文本,则标签会显示在文本视图中(例如 Title ...) 要在视图中显示文本,请使用类 [developer.android.com/reference/android/text/Html.html],特别是 fromHTML() @ZoltanF 是对的,在 HTML 布局中使用 android:text="" 将显示字符串中的标签。 如果您想直接从 XML 使用 HTML 字符串,您可以在字符串中编码 HTML 特殊字符。但是,如果您想通过Html.fromHTML() 使用代码中的字符串,您必须 对特殊字符进行编码。奇怪!【参考方案4】:

Android 没有说明资源字符串类型的规范(例如 text/plain 或 text/html)。但是,有一种解决方法允许开发人员在 XML 文件中指定它。

    定义一个自定义属性以指定 android:text 属性为 html。 使用子类 TextView。

一旦定义了这些,您就可以在 xml 文件中使用 HTML 来表达自己,而无需再次调用 setText(Html.fromHtml(...))。我很惊讶这种方法不是 API 的一部分。

此解决方案的工作原理是 Android Studio 模拟器将文本显示为呈现的 HTML。

res/values/strings.xml(字符串资源为 HTML)

<resources>
<string name="app_name">TextViewEx</string>
<string name="string_with_html"><![CDATA[
       <em>Hello</em> <strong>World</strong>!
 ]]></string>
</resources>

layout.xml(仅相关部分)

声明自定义属性命名空间,并添加 android_ex:isHtml 属性。也可以使用 TextView 的子类。

<RelativeLayout
...
xmlns:android_ex="http://schemas.android.com/apk/res-auto"
...>

<tv.twelvetone.samples.textviewex.TextViewEx
    android:layout_
    android:layout_
    android:text="@string/string_with_html"
    android_ex:isHtml="true"
    />
 </RelativeLayout>

res/values/attrs.xml(定义子类的自定义属性)

 <resources>
<declare-styleable name="TextViewEx">
    <attr name="isHtml" format="boolean"/>
    <attr name="android:text" />
</declare-styleable>
</resources>

TextViewEx.java(TextView 的子类)

 package tv.twelvetone.samples.textviewex;

 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.Nullable;
 import android.text.Html;
 import android.util.AttributeSet;
 import android.widget.TextView;

public TextViewEx(Context context, @Nullable AttributeSet attrs) 
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewEx, 0, 0);
    try 
        boolean isHtml = a.getBoolean(R.styleable.TextViewEx_isHtml, false);
        if (isHtml) 
            String text = a.getString(R.styleable.TextViewEx_android_text);
            if (text != null) 
                setText(Html.fromHtml(text));
            
        
     catch (Exception e) 
        e.printStackTrace();
     finally 
        a.recycle();
    


【讨论】:

这种方法会更好,如果应用程序在多个地方使用 HTML 格式的字符串,而不是在每个地方调用 HTML.fromHtml。应用程序本身将有两个视图,一个用于普通视图,一个用于 HTML。【参考方案5】:

最新更新:

Html.fromHtml(string);//Android N 版本后弃用..

以下代码支持android N及以上版本...

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
textView.setText(Html.fromHtml(yourHtmlString,Html.FROM_HTML_MODE_LEGACY));


else 

textView.setText(Html.fromHtml(yourHtmlString));

【讨论】:

【参考方案6】:
  String termsOfCondition="<font color=#cc0029>Terms of Use </font>";
  String commma="<font color=#000000>, </font>";
  String privacyPolicy="<font color=#cc0029>Privacy Policy </font>";
  Spanned text=Html.fromHtml("I am of legal age and I have read, understood, agreed and accepted the "+termsOfCondition+commma+privacyPolicy);
        secondCheckBox.setText(text);

【讨论】:

【参考方案7】:

当我从服务器接收到字符串 HTML 时,我没有机会将 CDATA 放入 xml 中。

这是我从服务器得到的:

<p>The quick brown&nbsp;<br />
fox jumps&nbsp;<br />
 over the lazy dog<br />
</p>

这似乎更复杂,但解决方案要简单得多。

private TextView textView;

protected void onCreate(Bundle savedInstanceState)  
.....
textView = (TextView) findViewById(R.id.text); //need to define in your layout
String htmlFromServer = getHTMLContentFromAServer(); 
textView.setText(Html.fromHtml(htmlFromServer).toString());


希望对您有所帮助! 灵儿

【讨论】:

getHTMLContentFromAServer() 函数的实现在哪里【参考方案8】:

如果您想在 Android 应用中显示 html 脚本,例如 TextView

请遵循此代码

Kotlin

var stringvalue = "Your Sting"

yourTextVew.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
            Html.fromHtml(stringvalue, Html.FROM_HTML_MODE_COMPACT)
         else 
            Html.fromHtml(stringvalue)
        

Java

String stringvalue = "Your String";

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
                   yourTextVew.setText(Html.fromHtml(stringvalue, Html.FROM_HTML_MODE_COMPACT))
                 else 
                   yourTextVew.setText( Html.fromHtml(stringvalue))
                

【讨论】:

以上是关于从 XML 中的 html 格式的字符串资源设置 TextView 文本的主要内容,如果未能解决你的问题,请参考以下文章

android listview中的文字大小能在string.xml里设置吗

如何限制 Rails 路由文件中的资源格式

Xml 反序列化。是不是可以从 xml 保存字符串格式?

如何从对话框中的主活动更新 ImageButton 的图像资源

AJAX中的dataType

Android xml 格式 随笔