Đặt văn bản TextView từ tài nguyên chuỗi được định dạng html trong XML


195

Tôi có một số chuỗi cố định bên trong của tôi strings.xml, đại loại như:

<resources>
    <string name="somestring">
        <B>Title</B><BR/>
        Content
    </string>
</resources>

và trong bố cục của tôi, tôi đã có một TextViewcái mà tôi muốn điền vào chuỗi định dạng html.

<TextView android:id="@+id/formattedtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/htmlstring"/>

nếu tôi làm điều này, nội dung của formattedtextchỉ là nội dung somestringbị tước của bất kỳ thẻ html nào và do đó không được định dạng.

Tôi biết rằng có thể đặt văn bản được định dạng theo chương trình với

.setText(Html.fromHtml(somestring));

bởi vì tôi sử dụng điều này trong các phần khác của chương trình của tôi, nơi nó đang hoạt động như mong đợi.

Để gọi hàm này, tôi cần một Activity, nhưng hiện tại bố cục của tôi chỉ là một chế độ xem tĩnh đơn giản hoặc ít hơn trong XML đơn giản và tôi muốn để nó theo cách đó, để cứu tôi khỏi chi phí tạo ra Activitychỉ để đặt một số bản văn.

Tôi đang nhìn một cái gì đó rõ ràng? Có phải là không thể nào cả? Bất kỳ trợ giúp hoặc giải pháp chào mừng!

Chỉnh sửa: Chỉ cần thử một số thứ và có vẻ như định dạng HTML trong xml có một số hạn chế:

  • các thẻ phải được viết thường

  • một số thẻ được đề cập ở đây không hoạt động, ví dụ: <br/>(có thể sử dụng \nthay thế)


1
Lâu nay tôi mới biết, nhưng tôi đã có thể sử dụng <br> chứ không phải \ n cho một dòng mới bằng cách sử dụng html cho TextView.
Tâm

2
Điều này có thể làm việc từ chỉ xml? Tôi có một tiền thưởng nhỏ trên câu trả lời. Tôi sẽ không nhận được như một câu trả lời thực tế tại thời điểm này tôi đã mã hóa xung quanh nó.
danny117

1
Tôi thấy thú vị khi không ai thực sự trả lời câu hỏi. OP nói rằng anh ấy biết cách thực hiện với fromHtml (), nhưng muốn thực hiện trực tiếp trong tệp bố cục (mặc dù, lý do không tốt ... bạn luôn có sẵn một hoạt động / ngữ cảnh nếu bạn đang vẽ màn hình). Không có câu trả lời nào đi sâu vào tác dụng của thẻ neo.
lilbyrdie

Câu trả lời:


481

Chỉ trong trường hợp bất kỳ ai tìm thấy điều này, có một sự thay thế đẹp hơn mà không được ghi lại (tôi đã vấp phải nó sau khi tìm kiếm hàng giờ và cuối cùng đã tìm thấy nó trong danh sách lỗi cho chính SDK Android). Bạn CÓ THỂ bao gồm HTML thô trong chuỗi XML, miễn là bạn bọc nó trong

<![CDATA[ ...raw html... ]]>

Thí dụ:

<string name="nice_html">
<![CDATA[
<p>This is a html-formatted string with <b>bold</b> and <i>italic</i> text</p>
<p>This is another paragraph of the same string.</p>
]]>
</string>

Sau đó, trong mã của bạn:

TextView foo = (TextView)findViewById(R.id.foo);
foo.setText(Html.fromHtml(getString(R.string.nice_html)));

IMHO, đây là một số đơn đặt hàng lớn hơn để làm việc với :-)


26
Chỉ cần thêm, bạn cũng có thể gạch chéo các dấu nháy đơn / dấu ngoặc đơn trong khối CDATA, do đó bạn có thể có những thứ như <b> can \ 't </ b> thay vì <b> can-apos; / b>
Bitbang3r

5
Điều này vẫn còn hoạt động? Tôi vừa thử nó và nó hiển thị theo nghĩa đen <p> và </ p>.
Peri Hartman

1
@PeriHartman Bạn cũng đã làm một Html.fromHtml(getString(R.string.nice_html))chút? :)
async

1
Trường hợp TextView foo = (TextView) findViewById (R.id.foo); foo.setText (Html.fromHtml (getString (R.opes.nice_html))); cần phải đi?
RustyIngles

2
Có cách nào để tránh "Html.fromHtml" không?
nhà phát triển Android

127

Vì câu trả lời hàng đầu ở đây là gợi ý điều gì đó sai (hoặc ít nhất là quá phức tạp), tôi cảm thấy điều này nên được cập nhật, mặc dù câu hỏi khá cũ:

Khi sử dụng tài nguyên Chuỗi trong Android, bạn chỉ cần gọi getString(...)từ mã Java hoặc sử dụng android:text="@string/..."trong XML bố cục của mình.

Ngay cả khi bạn muốn sử dụng đánh dấu HTML trong Chuỗi của mình, bạn không phải thay đổi nhiều:

Các ký tự duy nhất mà bạn cần thoát trong tài nguyên Chuỗi của bạn là:

  • dấu ngoặc kép: "trở thành\"
  • dấu ngoặc đơn: 'trở thành\'
  • ký hiệu: &trở thành &#38;hoặc&amp;

Điều đó có nghĩa là bạn có thể thêm đánh dấu HTML của mình mà không cần thoát các thẻ:

<string name="my_string"><b>Hello World!</b> This is an example.</string>

Tuy nhiên, để chắc chắn, bạn chỉ nên sử dụng <b>, <i><u>khi chúng được liệt kê trong tài liệu.

Nếu bạn muốn sử dụng các chuỗi HTML của mình từ XML , chỉ cần tiếp tục sử dụng android:text="@string/...", nó sẽ hoạt động tốt.

Sự khác biệt duy nhất là, nếu bạn muốn sử dụng các chuỗi HTML của mình từ mã Java , bạn phải sử dụng getText(...)thay vì getString(...)bây giờ, vì cái trước giữ kiểu và cái sau sẽ loại bỏ nó.

Nó là dễ dàng như vậy. Không có CDATA, không Html.fromHtml(...).

Bạn sẽ chỉ cần Html.fromHtml(...)nếu bạn đã mã hóa các ký tự đặc biệt của mình trong đánh dấu HTML. Sử dụng nó với getString(...)sau đó. Điều này có thể cần thiết nếu bạn muốn chuyển Chuỗi sang String.format(...).

Đây là tất cả được mô tả trong các tài liệu là tốt.

Biên tập:

Không có sự khác biệt giữa getText(...)với HTML không thoát (như tôi đã đề xuất) hoặc CDATAcác phần và Html.fromHtml(...).

Xem hình dưới đây để so sánh:

nhập mô tả hình ảnh ở đây


Của tôi đang tước nó đi. Tôi đang sử dụng mã sau:getResources().getText(R.string.codename)
Si8

3
Để giúp tốt hơn, tôi cần xem các đoạn trích Java / XML. Nhưng như tôi đã viết: Bạn là duy nhất chắc chắn nếu bạn đang sử dụng <b>, <i>, <u>. Các thẻ khác không phải lúc nào cũng được hỗ trợ.
kêu

1
Câu trả lời của bạn hoạt động và rất đơn giản. Chỉ cần đặt chuỗi của bạn vào chuỗi XML, với các thẻ html mong muốn và tham chiếu chuỗi đó từ tệp xml bố cục của bạn. Tôi đã sử dụng thẻ <sup>.
Peri Hartman

1
Của bạn là một giải pháp khác, không phải là giải pháp thay thế khác vì nó không hỗ trợ tất cả các thẻ, giống như các giải pháp khác. Tôi không thấy bất kỳ lợi thế nào trong giải pháp này khi giải pháp kia rất đơn giản.
Mobilepotato7

1
Như tôi đã trải nghiệm khi sử dụng "CDATA" có một vấn đề, ví dụ như thế này: <! [CDATA [... HTML ...]]> có 22 chữ cái và phần html có 10. vì vậy nếu bạn sử dụng HTML.fromhtml ( get chuỗi (...)) văn bản của bạn sẽ được hiển thị chính xác nhưng nội dung của văn bản cần khoảng trống 22 chữ cái. Tôi đã sử dụng trong listview và thấy không gian cỏ dại. vì vậy gettext () là TỐT HƠN.
David

16

Thoát các thẻ HTML của bạn ...

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>

Đó là những gì các tài liệu nói: developer.android.com/intl/zh-TW/guide/topics/resource/, nhưng điều đó có đủ TextViewđể hiển thị HTML không?
Macude

3
Tôi đã thử nghiệm điều này và nếu bạn sử dụng nó từ mã nguồn java, nó vẫn ổn. Nhưng nếu bạn liên kết văn bản của mình trực tiếp từ bố cục XML, các thẻ được hiển thị trong chế độ xem văn bản (ví dụ: <B> Tiêu đề </ B> ...)
ZoltanF

Để hiển thị văn bản trong chế độ xem, hãy sử dụng lớp [ developer.android.com/reference/android/text/Html.html] , cụ thể fromHTML().
ekawas

@ZoltanF đã đúng, sử dụng android: text = "" từ bố cục với HTML sẽ hiển thị các thẻ trong chuỗi.
Andrew Mackenzie

1
Nếu bạn muốn sử dụng chuỗi HTML trực tiếp từ XML, bạn không được mã hóa các ký tự đặc biệt HTML trong chuỗi. Tuy nhiên, nếu bạn muốn sử dụng chuỗi từ mã thông qua Html.fromHTML()bạn phải mã hóa các ký tự đặc biệt. Lạ thật!
caw

11

Android không có thông số kỹ thuật để chỉ ra loại chuỗi tài nguyên (ví dụ: văn bản / thuần túy hoặc văn bản / html). Tuy nhiên, có một cách giải quyết sẽ cho phép nhà phát triển chỉ định điều này trong tệp XML.

  1. Xác định một thuộc tính tùy chỉnh để xác định rằng thuộc tính android: text là html.
  2. Sử dụng một TextView được phân lớp.

Khi bạn xác định những điều này, bạn có thể thể hiện bản thân bằng HTML trong các tệp xml mà không cần phải gọi setText (Html.fromHtml (...)) nữa. Tôi khá ngạc nhiên khi cách tiếp cận này không phải là một phần của API.

Giải pháp này hoạt động ở mức độ mà trình giả lập studio Android sẽ hiển thị văn bản dưới dạng HTML được hiển thị.

nhập mô tả hình ảnh ở đây

res / value / chuỗi.xml (tài nguyên chuỗi dưới dạng HTML)

<resources>
<string name="app_name">TextViewEx</string>
<string name="string_with_html"><![CDATA[
       <em>Hello</em> <strong>World</strong>!
 ]]></string>
</resources>

layout.xml (chỉ các phần có liên quan)

Khai báo không gian tên thuộc tính tùy chỉnh và thêm thuộc tính android_ex: isHtml. Cũng sử dụng lớp con của TextView.

<RelativeLayout
...
xmlns:android_ex="http://schemas.android.com/apk/res-auto"
...>

<tv.twelvetone.samples.textviewex.TextViewEx
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/string_with_html"
    android_ex:isHtml="true"
    />
 </RelativeLayout>

res / value / attrs.xml (xác định các thuộc tính tùy chỉnh cho lớp con)

 <resources>
<declare-styleable name="TextViewEx">
    <attr name="isHtml" format="boolean"/>
    <attr name="android:text" />
</declare-styleable>
</resources>

TextViewEx.java (lớp con của TextView)

 package tv.twelvetone.samples.textviewex;

 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.Nullable;
 import android.text.Html;
 import android.util.AttributeSet;
 import android.widget.TextView;

public TextViewEx(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewEx, 0, 0);
    try {
        boolean isHtml = a.getBoolean(R.styleable.TextViewEx_isHtml, false);
        if (isHtml) {
            String text = a.getString(R.styleable.TextViewEx_android_text);
            if (text != null) {
                setText(Html.fromHtml(text));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        a.recycle();
    }
}
}

Cách tiếp cận này sẽ tốt hơn, Nếu ứng dụng sử dụng các chuỗi được định dạng HTML ở nhiều nơi thay vì gọi HTML.fromHtml ở mọi nơi. Bản thân ứng dụng sẽ có hai chế độ xem một cho bình thường và một cho HTML.
Manju

10

Cập nhật mới nhất:

Html.fromHtml(string);// không dùng nữa sau các phiên bản Android N ..

Mã sau hỗ trợ cho phiên bản Android N trở lên ...

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(yourHtmlString,Html.FROM_HTML_MODE_LEGACY));
}

else 
{
textView.setText(Html.fromHtml(yourHtmlString));
}

3
  String termsOfCondition="<font color=#cc0029>Terms of Use </font>";
  String commma="<font color=#000000>, </font>";
  String privacyPolicy="<font color=#cc0029>Privacy Policy </font>";
  Spanned text=Html.fromHtml("I am of legal age and I have read, understood, agreed and accepted the "+termsOfCondition+commma+privacyPolicy);
        secondCheckBox.setText(text);

2

Tôi có một trường hợp khác khi tôi không có cơ hội đưa CDATA vào xml khi tôi nhận được chuỗi HTML từ máy chủ.

Đây là những gì tôi nhận được từ một máy chủ:

<p>The quick brown&nbsp;<br />
fox jumps&nbsp;<br />
 over the lazy dog<br />
</p>

Có vẻ phức tạp hơn nhưng giải pháp đơn giản hơn nhiều.

private TextView textView;

protected void onCreate(Bundle savedInstanceState) { 
.....
textView = (TextView) findViewById(R.id.text); //need to define in your layout
String htmlFromServer = getHTMLContentFromAServer(); 
textView.setText(Html.fromHtml(htmlFromServer).toString());

}

Hy vọng nó giúp!
Linh


4
Việc triển khai hàm getHTMLContentFromAServer () ở đâu
Pallavi
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.