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


195

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

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

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

<TextView android:id="@+id/formattedtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/htmlstring"/>

如果执行此操作,则的内容formattedtext只是somestring剥离所有html标记的内容,因此未格式化。

我知道可以通过编程方式设置带格式的文本

.setText(Html.fromHtml(somestring));

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

要调用此函数,我需要一个Activity,但是目前,我的布局只是纯XML中的一个或多或少的简单静态视图,我宁愿以这种方式保留它,从而免去了创建Activityjust设置某些对象的开销。文本。

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

编辑:只是尝试了一些事情,似乎xml中的HTML格式有一些限制:

  • 标签必须写成小写

  • 例如,此处提到的某些标签不起作用(例如<br/>,可以使用\n


1
我知道已经很长时间了,但是我可以使用<br>而不是\ n来使用html作为TextView来换行。

2
可以仅通过xml进行工作吗?我对答案有一个小小的悬赏。在这一点上,我已经不作任何实际回答了。
danny117

1
我发现没有人真正回答这个问题很有趣。OP表示他知道如何使用fromHtml()进行操作,但希望直接在布局文件中进行操作(尽管原因并不理想...如果您继续绘制,则始终有可用的活动/上下文屏幕)。也没有一个答案深入到锚标记的作用。
lilbyrdie 2015年

Answers:


481

以防万一有人找到它,还有一个更好的替代方法尚未记录(我在搜索了几个小时后绊了一下,最后在Android SDK本身的错误列表中找到了它)。您CAN包括在strings.xml中原始的HTML,只要你把它包装

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

例:

<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 of the same string.</p>
]]>
</string>

然后,在您的代码中:

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

恕我直言,这比使用:-)好几个数量级


26
只需添加一下,您还可以在CDATA块内反斜杠转义撇号/单引号,因此您可以使用<b>不能</ b>之类的东西,而不是无限丑陋的<b> ca n't < / b>
Bitbang3r 2011年

5
这仍然有效吗?我只是尝试过,它实际上显示了<p>和</ p>。
佩里·哈特曼

1
@PeriHartman你也做了Html.fromHtml(getString(R.string.nice_html))吗?:)
异步

1
TextView foo =(TextView)findViewById(R.id.foo); foo.setText(Html.fromHtml(getString(R.string.nice_html)));; 需要去?
RustyIngles 2014年

2
有没有办法避免“ Html.fromHtml”?
Android开发人员

126

由于这里的最高答案表明有问题(或至少过于复杂),因此我认为应该对此进行更新,尽管问题已经很久了:

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

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

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

  • 双引号:"变为\"
  • 单引号:'变为\'
  • “&”号:&变为&#38;&amp;

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

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

然而,可以肯定,你应该只使用<b><i><u>为它们在文档中列出。

如果要使用XML的HTML字符串,只需继续使用android:text="@string/...",它将正常工作。

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

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

Html.fromHtml(...)当您确实在HTML标记中编码了特殊字符时才需要。getString(...)然后使用它。如果要将String传递给,则可能有必要String.format(...)

文档中也对此进行了描述。

编辑:

有什么区别getText(...)与转义HTML(因为我已经提出),或CDATA部分和Html.fromHtml(...)

请参见下图进行比较:

在此处输入图片说明


我的正在剥离。我正在使用以下代码:getResources().getText(R.string.codename)
Si8 2013年

3
为了提供更好的帮助,我需要查看Java / XML摘录。但正如我已经写了:你是唯一可以肯定的,如果你正在使用<b><i><u>。并非总是支持其他标签。
caw

1
您的答案很简单。只需将您的字符串放入带有所需html标签的strings.xml中,然后从布局xml文件中引用它即可。我使用了<sup>标签。
佩里·哈特曼

1
您的解决方案是另一种解决方案,而不是其他解决方案的替代方案,因为它不像其他解决方案那样支持所有标签。当另一个非常简单时,我看不到此解决方案的任何优势。
mobilepotato7 2015年

1
正如我使用“ CDATA”时遇到的问题一样,例如:<![CDATA [... HTML ...]]>具有22个字母,而html部分则为10。因此,如果您使用HTML.fromhtml( getstring(...))您的文本将正确显示,但文本内容需要22个字母空格。我在列表视图中使用过,看到过杂草丛生的空间。所以gettext()更好。
戴维(David

16

转义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吗?
Macarse 2010年

3
我已经测试过了,如果您从Java源代码中使用它,那就很好了。但是,如果您直接从布局XML关联文本,则标记将显示在文本视图中(例如<B> Title </ B> ...)
ZoltanF 2011年

要在视图中显示文本,请专门使用[ developer.android.com/reference/android/text/Html.html]fromHTML()
ekawas 2011年

@ZoltanF是正确的,在HTML布局中使用android:text =“”将在字符串中显示标签。
Andrew Mackenzie 2013年

1
如果要直接从XML使用HTML字符串,则不能在字符串中编码HTML特殊字符。然而,如果你想要使用的代码串通过Html.fromHTML(),你必须编码特殊字符。奇怪!
CAW

11

Android没有规范来指示资源字符串的类型(例如text / plain或text / html)。但是,有一种解决方法可以使开发人员在XML文件中指定此方法。

  1. 定义一个自定义属性,以指定android:text属性为html。
  2. 使用子类化的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_width="wrap_content"
    android:layout_height="wrap_content"
    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视图。
Manju

10

最新更新:

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

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

2

当我没有机会从服务器接收字符串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());

}

希望能帮助到你!
林氏


4
getHTMLContentFromAServer()函数的实现在哪里
Pallavi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.