HTML trong tài nguyên chuỗi?


120

Tôi biết tôi có thể đặt các thẻ HTML thoát trong tài nguyên chuỗi. Tuy nhiên, nhìn vào mã nguồn của ứng dụng Danh bạ, tôi có thể thấy rằng họ có cách không cần phải mã hóa HTML. Trích dẫn từ ứng dụng Danh bạ string.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>

Thật không may, khi tôi thử một cái gì đó tương tự (như Hello, <b>World</b>!), getString()trả về chuỗi không có thẻ (tôi có thể thấy điều đó tronglogcat ). Tại sao vậy? Làm cách nào để lấy chuỗi gốc, với các thẻ và mọi thứ? Ứng dụng Danh bạ hoạt động như thế nào?

Câu trả lời:


199

Bạn cũng có thể bao quanh html của mình trong một CDATAkhối và getString()sẽ trả về HTML thực của bạn. Như vậy:

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

Bây giờ khi bạn thực hiện một getString(R.string.foo)chuỗi sẽ là HTML. Nếu bạn cần hiển thị HTML (với liên kết như được hiển thị) qua một trình có thể nhấp, TextViewbạn cần thực hiện Html.fromHtml(...)lệnh gọi để nhận văn bản có thể mở rộng.


1
Không, bạn chắc chắn nên xem câu trả lời của Felix. CDATA là không cần thiết.
caw

4
@MarcoW. Câu trả lời của Felix là đúng nhưng sử dụng CDATA giúp chúng ta không phải lo lắng về các thẻ html. Câu trả lời này phải là câu trả lời chính xác.
slhddn

3
Nếu bạn có liên kết trong chuỗi, đừng quên thêm textView.setMovementMethod (LinkMovementMethod.getInstance ());
Adarsh ​​Urs

1
Tôi đã phải sử dụng \"cho styletài sản, mặc dù. Ví dụ<a style=\"...\">link</a>
Fabricio

1
CDATA cung cấp cho bạn sự linh hoạt hơn rất nhiều khi tạo kiểu chuỗi bằng các thẻ HTML. Tôi đồng ý rằng đó là cách để đi 100%!
Droid Chris

89

Nó dường như getString()chỉ có vậy - nhận được một chuỗi . Để sử dụng điều này, bạn phải sử dụng getText()(và không cần nữa Html.fromHtml()), tức là:

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

Tuy nhiên, có vẻ như thuộc android:texttính cũng làm điều tương tự và những điều sau đây là tương đương:

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

Và trong strings.xml:

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

28
Xin lưu ý rằng chỉ các thẻ được hỗ trợ là <b>, <i>, <u>: developer.android.com/guide/topics/resources/…
Snicolas

2
@pawegio chắc chắn ý bạn là \ngì?
Felix

7
@Snicolas: nó hỗ trợ nhiều hơn 3 thẻ được đề cập trong tài liệu: nó hỗ trợ <b>, <i>, <u>, <big>, <small>, <sup>, <sub>, <strike>, <li>, <marquee>, <a>, <font> và <annotation> (xem github.com/android/platform_frameworks_base/blob/… )
rve

1
Thật không may khi sử dụng phương pháp này, các biến trong chuỗi không được phép
Alessandro Muzzi

1
<font> được hỗ trợ tại api23, nhưng api10 thì không.
ảo

54

Giải pháp tốt nhất là sử dụng tài nguyên theo cách:

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

và hơn là hiển thị nó với:

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

Hãy thử sử dụng tài nguyên đó mà không có <![CDATA[ ]]>và có tv.setText(getText(R.string.htmlsource));và bạn sẽ thấy sự khác biệt.


Cảm ơn bạn đã giải vấn đề này thực sự giúp tôi
Alsemany

Ngay cả với một tệp HTML rất lớn và phức tạp?
Supuhstar

Cái này có hỗ trợ thẻ <font> không?
Rohit Singh

1

Tôi biết đây là một câu hỏi cũ nhưng có vẻ như câu trả lời hiệu quả nhất vẫn chưa được đề xuất.

Chỉ cần sử dụng các HTML-escapedký tự để nó không được xử lý bởi getStringnhưng nó sẽ được xử lý bởi HtmlCompact.fromHtml(hoặc cũ hơnHtml.fromHtml ).

Điều này cũng hỗ trợ nhiều thẻ hơn như liên kết HTML, v.v., không chỉ định dạng như getString phương pháp.

Ví dụ một cái gì đó như thế này sẽ hoạt động:

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

Trong trường hợp của bạn, bạn thay thế <bằng &lt;như thế này:

<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

nó hoạt động cho tôi mà không có khối 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`

Tôi sử dụng nó trong bố cục.

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

-1

Ý tưởng: đặt HTML trong các tệp có định dạng JSON và lưu trữ chúng trong / res / raw. (JSON ít kén chọn hơn)

Lưu trữ các bản ghi dữ liệu như thế này trong một đối tượng mảng:

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

Để đọc dữ liệu trong ứng dụng của bạn:

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

Cuối cùng, Datalớp chỉ là một vùng chứa các biến công khai để dễ dàng truy cập ...

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

Nó có vẻ hơi quá kỹ thuật, tại sao không lưu nó trong html thay vì json?
Misca
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.