字符串资源中的HTML?


120

我知道我可以将转义的HTML标记放在字符串资源中。但是,查看Contacts应用程序的源代码,我可以看到它们具有不必编码HTML的方式。引用联系人应用程序的strings.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)。这是为什么?如何获得带有标签和所有内容的原始字符串?联系人应用程序如何执行?

Answers:


199

您也可以将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。如果您需要通过clickable渲染HTML(带有如图所示的链接),则TextView需要执行Html.fromHtml(...)调用以获取可扩展文本。


1
不,您一定会看到Felix的答案。不需要CDATA。
CAW

4
@MarcoW。Felix的回答是正确的,但是使用CDATA可以帮助我们不必担心html标签。这个答案应该是正确的答案。
slhddn 2014年

3
如果字符串中有链接,请不要忘记添加textView.setMovementMethod(LinkMovementMethod.getInstance());。
Adarsh Urs,2015年

1
我不得不使用\"style财产,虽然。示例<a style=\"...\">link</a>
Fabricio

1
使用HTML标签样式化字符串时,CDATA为您提供了更多的灵活性。我同意这是100%要走的路!
Droid Chris

89

似乎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>

28
请注意,只有支持的代码均<B>,<I>,<U>:developer.android.com/guide/topics/resources/...
Snicolas

2
@pawegio当然是您的意思\n吗?
Felix

7
@Snicolas:它确实支持超过文档中提到的3个标签:它支持<b>,<i>,<u>,<big>,<small>,<sup>,<sub>,<strike>, <LI>,<选取框>,<A> <font>和<注释>(参见github.com/android/platform_frameworks_base/blob/...
RVE

1
不幸的是,使用此方法时,不允许使用字符串中的变量
Alessandro Muzzi,2016年

1
api23支持<font>,但api10不支持。
illusionJJ

54

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

<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));,您将看到差异。


谢谢您的回答,这确实帮助了我
Alsemany 2015年

即使使用非常大且复杂的HTML文件?
Supuhstar

是否支持<font>标记?
罗希特·辛格

1

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

只需使用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>

0

它对我有用,没有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"
    />

-1

想法:将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;
    }
}

似乎有点工程化,为什么不将其保存为html而不是json?
米斯卡
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.