HTML dalam sumber daya string?

120

Saya tahu saya bisa meletakkan tag HTML yang lolos dalam sumber daya string. Namun, melihat kode sumber untuk aplikasi Kontak saya dapat melihat bahwa mereka memiliki cara untuk tidak harus menyandikan HTML. Kutipan dari aplikasi Kontak 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>

Sayangnya, ketika saya mencoba sesuatu yang serupa (seperti Hello, <b>World</b>!), getString()mengembalikan string tanpa tag (saya bisa melihatnya di logcat). Mengapa demikian? Bagaimana saya bisa mendapatkan string asli, dengan tag dan semuanya? Bagaimana aplikasi Kontak melakukannya?

Felix
sumber

Jawaban:

199

Anda juga dapat mengapit html Anda dalam satu CDATAblok juga dan getString()akan mengembalikan HTML Anda yang sebenarnya. Seperti:

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

Sekarang ketika Anda melakukan getString(R.string.foo)string akan menjadi HTML. Jika Anda perlu merender HTML (dengan tautan seperti yang ditunjukkan) melalui yang dapat diklik, TextViewAnda harus melakukan Html.fromHtml(...)panggilan untuk mendapatkan teks yang dapat dipisahkan.

Donn Felker
sumber
1
Tidak, Anda pasti harus melihat jawaban Felix. CDATA tidak diperlukan.
gak
4
@Tokopedia Jawaban Felix benar, tetapi menggunakan CDATA membantu kita untuk tidak khawatir tentang tag html. Jawaban ini haruslah jawaban yang benar.
slhddn
3
Jika Anda memiliki link dalam string, jangan lupa untuk menambahkan textView.setMovementMethod (LinkMovementMethod.getInstance ());
Adarsh ​​Urs
1
Tapi aku harus menggunakan \"untuk styleproperti. Contoh<a style=\"...\">link</a>
Fabricio
1
CDATA memberi Anda lebih banyak fleksibilitas saat menata string dengan tag HTML. Saya setuju bahwa itulah cara untuk mencapai 100%!
Droid Chris
89

Tampaknya getString()melakukan hal itu - mendapat string . Untuk menggunakan ini, Anda harus menggunakan getText()(dan tidak lebih Html.fromHtml()), yaitu:

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

Namun, tampaknya android:textproperti tersebut melakukan hal yang sama, dan berikut ini adalah padanannya:

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

Dan di strings.xml:

<string name="my_styled_text">Hello, <b>World</b>!</string>
Felix
sumber
28
Harap dicatat bahwa hanya tag yang didukung adalah <b>, <i>, <u>: developer.android.com/guide/topics/resources/…
Snicolas
2
@pawegio pasti maksudmu \n?
Felix
7
@Snicolas: mendukung lebih dari 3 tag yang disebutkan dalam dokumentasi: mendukung <b>, <i>, <u>, <big>, <small>, <sup>, <sub>, <strike>, <li>, <marquee>, <a>, <font> dan <penjelasan> (lihat github.com/android/platform_frameworks_base/blob/... )
rve
1
Sayangnya menggunakan metode ini, variabel dalam string tidak diperbolehkan
Alessandro Muzzi
1
<font> didukung di api23, tetapi api10 tidak.
ilusi
54

Solusi terbaik adalah menggunakan sumber daya dengan cara:

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

dan kemudian menampilkannya dengan:

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

Cobalah untuk menggunakan sumber daya itu tanpa <![CDATA[ ]]>dan dengan tv.setText(getText(R.string.htmlsource));dan Anda akan melihat perbedaannya.

pengguna1006786
sumber
Terima kasih atas jawaban ini, ini sangat membantu saya
Alsemany
Bahkan dengan file HTML yang sangat besar dan kompleks?
Supuhstar
Apakah ini mendukung tag <font>?
Rohit Singh
1

Saya tahu ini adalah pertanyaan lama tetapi tampaknya jawaban yang paling efisien belum diajukan.

Cukup gunakan HTML-escapedkarakter sehingga tidak akan diproses getStringtetapi akan diproses oleh HtmlCompact.fromHtml(atau yang lebih tua Html.fromHtml).

Ini juga mendukung lebih banyak tag seperti tautan HTML dll, tidak hanya pemformatan seperti getStringmetode.

Misalnya sesuatu seperti ini seharusnya berfungsi:

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

Dalam kasus Anda, Anda mengganti <dengan &lt;seperti ini:

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

itu bekerja untuk saya tanpa blok 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`

Saya menggunakannya dalam tata letak.

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

Ide: letakkan HTML dalam file berformat JSON dan simpan di / res / raw. (JSON kurang pilih-pilih)

Simpan catatan data seperti ini dalam objek array:

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

Untuk membaca data di aplikasi Anda:

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

Terakhir, Datakelas hanyalah wadah variabel publik untuk memudahkan akses ...

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;
    }
}
Seseorang disuatu tempat
sumber
Tampaknya agak terlalu direkayasa, mengapa tidak menyimpannya dalam html daripada di json?
Misca