Android Spanned, SpannedString, Spannable, SpannableString và CharSequence


92

Mời Android nhiều giao diện tất cả liên quan đến văn bản và chuỗi: Spanned, SpannedString, Spannable, SpannableStringCharSequence.

Tôi đã sử dụng tất cả các điều trên trong các trường hợp khác nhau thường sau khi sử dụng Html.fromHtml()để hiển thị văn bản có thể liên kết bên trong một TextViewđể áp dụng một số kiểu cho nó.

Tôi đã cố gắng hiểu mục đích / cách sử dụng của các giao diện này từ tài liệu chính thức của Android và không thành công vì nó khá khó hiểu .. Mục đích của các giao diện này là gì? trong các tình huống nào nó thường sử dụng chúng nhất? Những trường hợp nào là tốt nhất để tránh sử dụng chúng? Có bất kỳ tác động hiệu suất rõ ràng nào cần được xem xét khi sử dụng bất kỳ một trong số chúng không?

Nếu bất cứ ai có thể cung cấp một lời giải thích hợp lý, nó sẽ được đánh giá cao.

Câu trả lời:


148

Mục đích của các giao diện này là gì?

sơ đồ từ yuml.me/edit/5f8da6cb CharSequencelà một giao diện Java tiêu chuẩn đại diện cho một chuỗi các ký tự. Stringlà cách triển khai cụ thể được sử dụng phổ biến nhất CharSequence, tiếp theo là StringBuilder.

Spannedlà một CharSequencevới "nhịp" cho biết định dạng áp dụng cho các phần của văn bản, nơi không thể sửa đổi những khoảng đó.

Spannablelà một Spanned, bổ sung khả năng sửa đổi các nhịp (để thêm hoặc xóa định dạng), nhưng không sửa đổi chính văn bản.

SpannedStringlà một triển khai cụ thể của Spannedgiao diện.

SpannableStringlà một triển khai cụ thể của Spannablegiao diện.

trong những tình huống nào nó thường sử dụng chúng nhất?

Khi có một phương thức trả về một (ví dụ: getText()trên an EditText) hoặc khi có một phương thức nhận một làm tham số (ví dụ: setText()trên a TextView). sơ đồ từ yuml.me/edit/35c8f39f

Trường hợp sử dụng được trích dẫn của bạn Html.fromHtml()có lẽ là phổ biến nhất trong phát triển Android thông thường, vì a TextViewvới a Spannedcó trọng lượng nhẹ hơn nhiều so với a WebView. Tuy nhiên, có những trường hợp sử dụng khác, chẳng hạn như:

Những trường hợp nào là tốt nhất để tránh sử dụng chúng?

Chúng đặc biệt khủng khiếp trong việc chống lại chứng hói đầu, loại bỏ tuyết, sửa chữa máy bơm nhiệt, làm bánh ngọt, v.v.

:-)

Có bất kỳ tác động hiệu suất rõ ràng nào cần được xem xét khi sử dụng bất kỳ một trong số chúng không?

Theo định nghĩa, các giao diện không có "tác động đến hiệu suất" - chúng chỉ là mô tả của một API.

Tôi không biết rằng SpannableStringnó chậm hơn đáng kể so SpannedStringvới bất kỳ hoạt động cụ thể nào. Tuy nhiên, SpannableStringBuilder(cho phép thao tác văn bản ngoài các nhịp định dạng văn bản đó) cũng có thể chậm hơn một chút so với SpannableStringhoặc SpannedStringđối với nhiều thứ khác nhau. Tuy nhiên, sự khác biệt về hiệu suất có đủ quan trọng hay không sẽ phụ thuộc vào cách sử dụng.


4
Vì tài liệu chính thức không hoạt động, bạn lấy những thông tin này từ đâu? Nguồn thủ công duyệt theo cách khó khăn?
Pacerier

11
@Pacerier: Tôi không chắc bạn đang đề cập đến phần nào của câu trả lời này. Ví dụ: cấu trúc phân cấp lớp được mô tả trong câu trả lời này chắc chắn nhất đến từ tài liệu, cụ thể là JavaDocs. Ngược lại, sự thiếu tiện ích của những thứ này để chống lại chứng hói đầu đến từ quan sát cá nhân.
CommonsWare

@CommonsWare, điều đó có nghĩa là một chuỗi có biểu tượng mặt cười ở giữa sẽ được coi là một spannableStringvà không phải là một chuỗi bình thường .. bởi vì tôi đang phải đối mặt với độ trễ lớn setText(my_string) khi my_stringcó biểu tượng mặt cười trong đó (như của watsapp) so với chuỗi bình thường. . (trong đó có văn bản chỉ đơn giản) vui lòng ném một số ánh sáng ... bằng cách nào đó tôi tin rằng smilleys là gì, nhưng văn bản (unicode) chỉ
eRaisedToX

1
@eRaisedToX: Biểu tượng mặt cười có thể được triển khai dưới dạng biểu tượng cảm xúc hoặc hình ảnh. AFAIK, biểu tượng cảm xúc sẽ là các ký tự Unicode riêng lẻ và có lẽ có thể nằm trong một chuỗi thông thường. Hình ảnh sẽ yêu cầu ImageSpanmà lần lượt yêu cầu SpannableString.
CommonsWare

Có lẽ là chắc chắn ... nhưng hãy thử xử lý biểu tượng cảm xúc và sử dụng Chuỗi thường xuyên và bạn sẽ trở lại ngay với việc chống lại chứng hói đầu. Editables và SpannableStringBuilders là người bạn tốt nhất của bạn khi nói đến việc triển khai biểu tượng cảm xúc. Tôi thấy rằng mặc dù đúng, chúng chỉ đơn giản là unicode, nhưng đó là cách bạn mã hóa việc xác định khoảng biểu tượng cảm xúc và cài đặt khoảng thời gian biểu tượng cảm xúc là nơi chi phí hiệu suất của bạn. Hãy cẩn thận khi sử dụng Thư viện biểu tượng cảm xúc của người khác nếu bạn không biết cách chúng hoạt động ...
JamisonMan111 Ngày

43

Chuỗi

A Stringlà bất biến (nghĩa là văn bản không thể thay đổi). Nó cũng không có bất kỳ nhịp nào liên quan đến nó. (Khoảng cách là phạm vi trên văn bản bao gồm thông tin tạo kiểu như màu sắc, tô sáng, in nghiêng, liên kết, v.v.) Vì vậy, bạn có thể sử dụng một Stringkhi văn bản của bạn không cần thay đổi và không cần bất kỳ kiểu dáng nào.

StringBuilder

A StringBuildercó văn bản có thể thay đổi, vì vậy bạn có thể sửa đổi nó mà không cần tạo một đối tượng mới. Tuy nhiên, nó không có bất kỳ thông tin nhịp nào. Nó chỉ là văn bản thuần túy. Vì vậy, hãy sử dụng a StringBuilderkhi bạn cần thay đổi văn bản, nhưng bạn không quan tâm đến việc tạo kiểu cho nó.

SpannedString

A SpannedStringcó văn bản bất biến (như a String) và thông tin khoảng không thay đổi. Nó là một triển khai cụ thể của các yêu cầu được xác định bởi Spannedgiao diện. Sử dụng a SpannedStringkhi văn bản của bạn có kiểu nhưng bạn không cần thay đổi văn bản hoặc kiểu sau khi tạo.

Lưu ý: Không có cái gọi là a SpannedStringBuildervì nếu văn bản thay đổi thì thông tin nhịp cũng rất có thể sẽ phải thay đổi.

SpannableString

A SpannableStringcó văn bản không thể thay đổi, nhưng thông tin nhịp của nó có thể thay đổi. Nó là một triển khai cụ thể các yêu cầu được xác định bởi Spannablegiao diện. Sử dụng một SpannableStringkhi văn bản của bạn không cần phải thay đổi nhưng kiểu dáng thì có.

SpannableStringBuilder

A SpannableStringBuildercó cả thông tin văn bản và nhịp có thể thay đổi. Nó là một triển khai cụ thể các yêu cầu được xác định bởi Spannablevà các Editablegiao diện (trong số những người khác). Sử dụng một SpannableStringBuilderkhi bạn cần cập nhật văn bản và kiểu của nó.

Trình tự Char

A CharSequencelà một giao diện và không phải là một lớp cụ thể. Điều đó có nghĩa là nó chỉ định nghĩa một danh sách các quy tắc phải tuân theo cho bất kỳ lớp nào thực thi nó. Và tất cả các lớp được đề cập ở trên đều thực hiện nó. Vì vậy, bạn có thể sử dụng a CharSequencekhi bạn muốn tổng quát hóa loại đối tượng mà bạn có để linh hoạt tối đa. Bạn luôn có thể từ chối nó xuống một Stringhoặc SpannableStringBuilderhoặc bất cứ điều gì sau đó nếu bạn cần.


3
Tôi đánh giá cao cách bạn trình bày câu trả lời của mình, rất dễ đọc và dễ hiểu, cảm ơn
JamisonMan111 Ngày
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.