Android 字符串资源中的 HTML?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2667319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:51:09  来源:igfitidea点击:

HTML in string resource?

android

提问by Felix

I know I can put escaped HTML tags in string resources. However, looking at the source code for the Contacts application I can see that they have a way of not having to encode the HTML. Quote from the Contacts application strings.xml:

我知道我可以将转义的 HTML 标签放在字符串资源中。但是,查看联系人应用程序的源代码,我可以看到他们有一种不必对 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>

Unfortunately, when I try something similar (like Hello, <b>World</b>!), getString()returns the string without the tags (I can see that in logcat). Why is that? How can I get the original string, with tags and everything? How is the Contacts application doing it?

不幸的是,当我尝试类似的东西(比如Hello, <b>World</b>!)时,getString()返回没有标签的字符串(我可以在 中看到logcat)。这是为什么?如何获得带有标签和所有内容的原始字符串?通讯录应用程序是如何做到的?

采纳答案by Felix

It seems getString()does just that -- gets a string. To use this, you have to use getText()(and no more Html.fromHtml()), i.e.:

似乎getString()就是这样——获取一个字符串。要使用它,您必须使用getText()(并且不再使用Html.fromHtml()),即:

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

However, it seems the android:textproperty does just the same thing, and the following is equivalent:

但是,该android:text属性似乎做同样的事情,以下是等效的:

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

And in strings.xml:

并在strings.xml

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

回答by Donn Felker

You can also surround your html in a CDATAblock as well and getString()will return your actual HTML. Like such:

您也可以将 html 包含在一个CDATA块中,并getString()返回您的实际 HTML。像这样:

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

Now when you perform a getString(R.string.foo)the string will be HTML. If you need to render the HTML (with the link as shown) via a clickable TextViewyou'd need to perform a Html.fromHtml(...)call to get the spannable text.

现在,当您执行 a 时getString(R.string.foo),字符串将是 HTML。如果您需要通过可点击呈现 HTML(带有如图所示的链接),TextView您需要执行Html.fromHtml(...)调用以获取可跨文本。

回答by user1006786

The best solution is to use resources in a way:

最好的解决方案是以某种方式使用资源:

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

and than display it with:

然后显示它:

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

Try to use that resource without <![CDATA[ ]]>and with tv.setText(getText(R.string.htmlsource));and you will see the difference.

尝试在没有<![CDATA[ ]]>tv.setText(getText(R.string.htmlsource));有的情况下使用该资源,您会看到不同之处。

回答by Andrew Glukhoff

it works for me without CDATA block.

它在没有 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`

I use it in layout.

我在布局中使用它。

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

回答by bio007

I know this is an old question but it seems the most efficient answer has not been proposed yet.

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

Just use HTML-escapedcharacters so it won't get processed by getStringbut it will be processed by HtmlCompact.fromHtml(or the older Html.fromHtml).

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

This also supports more tags like HTML links etc., not only formatting like getStringmethod.

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

For example something like this should work:

例如这样的事情应该工作:

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

In your case you replace <with &lt;like this:

在您的情况下,您<可以&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>

回答by Someone Somewhere

Idea: put the HTML in JSON-formatted files and store them in /res/raw. (JSON is less picky)

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

Store the data records like this in an array object:

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

[
    {
        "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
    }
]

To read the data in your app :

要读取应用程序中的数据:

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

Finally, the Dataclass is just a container of public variables for easy access...

最后,这个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;
    }
}