字符串资源中的 HTML? ?

我知道我可以把转义的 HTML 标记放在字符串资源中。但是,通过查看 Contacts 应用程序的源代码,我可以发现它们有一种不必编码 HTML 的方法。引自联系人应用程序 Xml:

<string name="contactsSyncPlug"><font fgcolor="#ffffffff">Sync your Google contacts!</font>
\nAfter syncing to your phone, your contacts will be available to you wherever you go.</string>

不幸的是,当我尝试类似的操作(比如 Hello, <b>World</b>!)时,getString()返回没有标记的字符串(我可以在 logcat中看到)。为什么?我怎样才能得到原始的字符串,包括标签和其他东西?联系人应用程序是如何做到这一点的?

95822 次浏览

看起来 getString()就是这么做的——得到一个 绳子。要使用它,你必须使用 getText()(不再使用 Html.fromHtml()) ,即:

mTextView.setText(getText(R.string.my_styled_text));

然而,看起来 android:text属性做同样的事情,并且下面是等价的:

<TextView android:text="@string/my_styled_text" />

strings.xml:

<string name="my_styled_text">Hello, <b>World</b>!</string>

您也可以将 HTML 包围在 CDATA块中,并且 getString()将返回实际的 HTML。就像这样:

<string name="foo"><![CDATA[Foo Bar <a href="foo?id=%s">baz</a> is cool]]></string>

现在执行 getString(R.string.foo)时,字符串将是 HTML。如果您需要通过一个可单击的 TextView来呈现 HTML (包含如图所示的链接) ,那么您需要执行一个 Html.fromHtml(...)调用来获得可跨文本。

最好的解决办法是以下列方式使用资源:

<string name="htmlsource"><![CDATA[<p>Adults are spotted gold and black on the crown, back and wings. Their face and neck are black with a white border; they have a black breast and a dark rump. The legs are black.</p><p>It is similar to two other golden plovers, Eurasian and Pacific. <h1>The American Golden Plover</h1> is smaller, slimmer and relatively longer-legged than Eurasian Golden Plover (<i>Pluvialis apricaria</i>) which also has white axillary (armpit) feathers. It is more similar to Pacific Golden Plover (<i>Pluvialis fulva</i>) with which it was once <b>considered</b> conspecific under the name \"Lesser Golden Plover\". The Pacific Golden Plover is slimmer than the American species, has a shorter primary projection, and longer legs, and is usually yellower on the back.</p><p>These birds forage for food on tundra, fields, beaches and tidal flats, usually by sight. They eat insects and crustaceans, also berries.</p>]]></string>

然后用以下方式展示:

Spanned sp = Html.fromHtml( getString(R.string.htmlsource));
tv.setText(sp);

尝试不使用 <![CDATA[ ]]>和使用 tv.setText(getText(R.string.htmlsource));使用该资源,您将看到差异。

想法: 将 HTML 放入 JSON 格式的文件中,并将它们存储在/res/raw 中(JSON 不那么挑剔)

将这样的数据记录存储在一个数组对象中:

[
{
"Field1": "String data",
"Field2": 12345,
"Field3": "more Strings",
"Field4": true
},
{
"Field1": "String data",
"Field2": 12345,
"Field3": "more Strings",
"Field4": true
},
{
"Field1": "String data",
"Field2": 12345,
"Field3": "more Strings",
"Field4": true
}
]

读取应用程序中的数据:

private ArrayList<Data> getData(String filename) {
ArrayList<Data> dataArray = new ArrayList<Data>();


try {
int id = getResources().getIdentifier(filename, "raw", getPackageName());
InputStream input = getResources().openRawResource(id);
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
String text = new String(buffer);


Gson gson = new Gson();
Type dataType = new TypeToken<List<Map<String, Object>>>() {}.getType();
List<Map<String, Object>> natural = gson.fromJson(text, dataType);


// now cycle through each object and gather the data from each field
for(Map<String, Object> json : natural) {
final Data ad = new Data(json.get("Field1"), json.get("Field2"),  json.get("Field3"), json.get("Field4"));
dataArray.add(ad);
}


} catch (Exception e) {
e.printStackTrace();
}


return dataArray;
}

最后,Data类只是一个容纳公共变量的容器,便于访问..。

public class Data {


public String string;
public Integer number;
public String somestring;
public Integer site;
public boolean logical;




public Data(String string, Integer number, String somestring, boolean logical)
{
this.string = string;
this.number = number;
this.somestring = somestring;
this.logical = logical;
}
}

它不需要 CDATA 块就可以工作。

<string name="menu_item_purchase" translatable="false"><font color="red">P</font><font color="orange">r</font><font color="yellow">e</font><font color="green">m</font><font color="white">i</font><font color="blue">u</font><font color="purple">m</font></string>`enter code here`

我在布局中使用它。

<item
android:id="@+id/nav_premium"
android:icon="@drawable/coins"
android:title="@string/menu_item_purchase"
/>

我知道这是一个老问题,但似乎最有效的答案还没有提出来。

只要使用 HTML-escaped字符,这样它就不会被 getString处理,但是它会被 HtmlCompact.fromHtml(或者旧的 Html.fromHtml)处理。

这也支持更多的标签,如 HTML 链接等,不仅像 getString方法格式。

例如,像这样的东西应该是有效的:

<string name="html_message">Hello &lt;b>World&lt;/b>.</string>


val text = getString(R.string.html_message)
val result = HtmlCompact.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY)

在你的例子中,你用 &lt;代替 <,如下所示:

<string name="contactsSyncPlug">&lt;font fgcolor="#ffffffff">Sync your Google contacts!&lt;/font> \nAfter syncing to your phone, your contacts will be available to you wherever you go.</string>