HTML in String-Ressource?

120

Ich weiß, dass ich maskierte HTML-Tags in Zeichenfolgenressourcen einfügen kann. Wenn ich mir jedoch den Quellcode für die Kontakte-Anwendung ansehe, kann ich feststellen, dass sie den HTML-Code nicht codieren müssen. Zitat aus der Kontakte-Anwendung 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>

Wenn ich etwas Ähnliches (wie Hello, <b>World</b>!) versuche , wird getString()der String leider ohne die Tags zurückgegeben (das kann ich in sehen logcat). Warum ist das so? Wie kann ich die Originalzeichenfolge mit Tags und allem erhalten? Wie macht die Kontaktanwendung das?

Felix
quelle

Antworten:

199

Sie können Ihr HTML auch in einem CDATABlock umgeben und getString()geben Ihr tatsächliches HTML zurück. Wie solche:

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

Wenn Sie nun eine ausführen, ist getString(R.string.foo)die Zeichenfolge HTML. Wenn Sie den HTML- Code (mit dem gezeigten Link) über eine anklickbare Datei rendern TextViewmüssen, müssen Sie einen Html.fromHtml(...)Aufruf ausführen , um den spannbaren Text zu erhalten.

Donn Felker
quelle
1
Nein, du solltest auf jeden Fall Felix 'Antwort sehen. CDATA ist nicht erforderlich.
Caw
4
@ MarcoW. Felix 'Antwort ist wahr, aber die Verwendung von CDATA hilft uns, uns keine Sorgen um HTML-Tags zu machen. Diese Antwort sollte die richtige sein.
Slhddn
3
Wenn die Zeichenfolge Links enthält, vergessen Sie nicht, textView.setMovementMethod (LinkMovementMethod.getInstance ()) hinzuzufügen.
Adarsh ​​Urs
1
Ich musste es jedoch \"für styleEigentum verwenden. Beispiel<a style=\"...\">link</a>
Fabricio
1
CDATA bietet Ihnen viel mehr Flexibilität beim Stylen von Zeichenfolgen mit HTML-Tags. Ich würde zustimmen, dass dies der richtige Weg ist, um 100% zu gehen!
Droid Chris
89

Es scheint getString()genau das zu tun - bekommt eine Zeichenfolge . Um dies zu verwenden, müssen Sie verwenden getText()(und nicht mehr Html.fromHtml()), dh:

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

Es scheint jedoch, dass die android:textEigenschaft genau dasselbe tut, und Folgendes ist äquivalent:

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

Und in strings.xml:

<string name="my_styled_text">Hello, <b>World</b>!</string>
Felix
quelle
28
Bitte beachten Sie, dass nur unterstützte Tags <b>, <i>, <u> sind: developer.android.com/guide/topics/resources/…
Snicolas
2
@pawegio meinst du doch \n?
Felix
7
@Snicolas: Es werden mehr als die 3 in der Dokumentation genannten Tags unterstützt: <b>, <i>, <u>, <big>, <small>, <sup>, <sub>, <strike>, <li>, <marquee>, <a>, <font> und <annotation> (siehe github.com/android/platform_frameworks_base/blob/… )
29.
1
Leider sind Variablen in der Zeichenfolge mit dieser Methode nicht zulässig
Alessandro Muzzi
1
<font> wird bei api23 unterstützt, api10 jedoch nicht.
IllusionJJ
54

Die beste Lösung besteht darin, Ressourcen folgendermaßen zu nutzen:

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

und dann mit anzeigen:

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

Versuchen Sie, diese Ressource ohne <![CDATA[ ]]>und mit zu verwenden, tv.setText(getText(R.string.htmlsource));und Sie werden den Unterschied sehen.

user1006786
quelle
Vielen Dank für diese Antwort, die mir wirklich geholfen hat
Alsemany
Auch mit einer sehr großen und komplexen HTML-Datei?
Supuhstar
Unterstützt dies das <font> -Tag?
Rohit Singh
1

Ich weiß, dass dies eine alte Frage ist, aber es scheint, dass die effizienteste Antwort noch nicht vorgeschlagen wurde.

Verwenden HTML-escapedSie einfach Zeichen, damit es nicht von verarbeitet wird, getStringsondern von HtmlCompact.fromHtml(oder dem älteren Html.fromHtml).

Dies unterstützt auch mehr Tags wie HTML-Links usw., nicht nur formatierungsähnliche getStringMethoden.

Zum Beispiel sollte so etwas funktionieren:

<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 Ihrem Fall ersetzen Sie <mit &lt;wie folgt aus :

<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>
bio007
quelle
0

es funktioniert bei mir ohne CDATA-Block.

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

Ich benutze es im Layout.

<item
    android:id="@+id/nav_premium"
    android:icon="@drawable/coins"
    android:title="@string/menu_item_purchase"
    />
Andrew Glukhoff
quelle
-1

Idee: Fügen Sie den HTML-Code in JSON-formatierte Dateien ein und speichern Sie sie in / res / raw. (JSON ist weniger wählerisch)

Speichern Sie die Datensätze wie folgt in einem Array-Objekt:

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

So lesen Sie die Daten in Ihrer 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;
}

Schließlich ist die DataKlasse nur ein Container mit öffentlichen Variablen für den einfachen Zugriff ...

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;
    }
}
Irgendwer irgendwo
quelle
Es scheint ein bisschen überentwickelt zu sein, warum nicht in HTML statt in json speichern?
Misca