Android Spanned, SpannedString, Spannable, SpannableString dan CharSequence

96

Penawaran Android berbagai antarmuka semua yang berkaitan dengan teks dan string: Spanned, SpannedString, Spannable, SpannableStringdan CharSequence.

Saya telah menggunakan semua hal di atas dalam berbagai skenario biasanya setelah menggunakan Html.fromHtml()untuk menampilkan teks yang dapat ditautkan di dalam a TextViewuntuk menerapkan beberapa gaya padanya.

Saya telah mencoba memahami tujuan / penggunaan antarmuka ini dari dokumentasi resmi Android dan gagal karena cukup membingungkan .. Apa tujuan antarmuka ini? dalam skenario mana yang paling umum untuk menggunakannya? Dalam kasus apa yang terbaik untuk menghindari penggunaannya? Apakah ada dampak kinerja yang jelas untuk dipertimbangkan saat menggunakan salah satunya?

Jika ada yang bisa memberikan penjelasan yang layak, itu akan sangat dihargai.

woot
sumber

Jawaban:

149

Apa tujuan dari antarmuka ini?

diagram dari yuml.me/edit/5f8da6cb CharSequenceadalah antarmuka Java standar yang mewakili urutan karakter. Stringadalah implementasi konkret yang paling umum digunakan CharSequence, diikuti oleh StringBuilder.

Spannedadalah CharSequencedengan "span" yang menunjukkan pemformatan untuk diterapkan ke bagian teks, di mana span tersebut tidak dapat diubah.

Spannableadalah Spanned, menambahkan kemampuan untuk mengubah bentang (untuk menambah atau menghapus pemformatan), tetapi tidak untuk mengubah teks itu sendiri.

SpannedStringadalah implementasi konkret dari Spannedantarmuka.

SpannableStringadalah implementasi konkret dari Spannableantarmuka.

dalam skenario mana yang paling umum untuk menggunakannya?

Ketika ada metode yang mengembalikan satu (misalnya, getText()pada EditText) atau ketika ada metode yang mengambilnya sebagai parameter (misalnya, setText()pada a TextView). diagram dari yuml.me/edit/35c8f39f

Kutipan kasus penggunaan Anda Html.fromHtml()mungkin yang paling umum dalam pengembangan Android konvensional, karena a TextViewdengan Spannedbobot yang jauh lebih ringan daripada a WebView. Namun, ada kasus penggunaan lain, seperti:

Dalam kasus apa yang terbaik untuk menghindari penggunaannya?

Mereka sangat buruk dalam memerangi kebotakan, menghilangkan salju, memperbaiki pompa panas, membuat souffle, dll.

:-)

Apakah ada dampak kinerja yang jelas untuk dipertimbangkan saat menggunakan salah satunya?

Antarmuka, menurut definisi, tidak memiliki "dampak kinerja" - antarmuka hanyalah deskripsi API.

Saya tidak menyadari bahwa SpannableStringsecara signifikan lebih lambat daripada SpannedStringpada operasi tertentu. Namun, SpannableStringBuilder(yang memungkinkan untuk memanipulasi teks selain span yang memformat teks itu) mungkin sedikit lebih lambat daripada SpannableStringatau SpannedStringuntuk berbagai hal. Apakah perbedaan kinerja cukup penting atau tidak akan tergantung pada penggunaan.

CommonsWare
sumber
4
Karena dokumen resmi tidak bersuara, dari mana Anda mendapatkan info ini? Sumber manual menjelajah dengan cara hardcore?
Pacerier
11
@Pacerier: Saya tidak yakin bagian mana dari jawaban ini yang Anda maksud. Misalnya, hierarki kelas yang dijelaskan dalam jawaban ini pasti berasal dari dokumentasi, khususnya JavaDocs. Sebaliknya, kurangnya kegunaan dari hal-hal ini untuk memerangi kebotakan berasal dari pengamatan pribadi.
CommonsWare
@CommonsWare, jadi apakah itu berarti bahwa string dengan smiley di antaranya akan dianggap sebagai spannableStringdan bukan yang normal .. karena saya menghadapi kelambatan yang sangat besar dengan setText(my_string) ketika my_stringmemiliki smiley di dalamnya (seperti yang ada di watsapp) dibandingkan dengan string normal. . (yang hanya memiliki teks biasa) mohon jelaskan ... entah bagaimana saya percaya bahwa smilleys hanyalah teks (unicode) saja
eRaisedToX
1
@eRaisedToX: Smiley dapat diimplementasikan sebagai emoji atau gambar. AFAIK, emoji adalah karakter Unicode individual dan mungkin dalam string biasa. Gambar akan membutuhkan ImageSpanyang pada gilirannya membutuhkan SpannableString.
CommonsWare
Mungkin yakin ... tapi cobalah berurusan dengan emoji dan gunakan String biasa dan Anda akan segera kembali memerangi kebotakan. Editables dan SpannableStringBuilders adalah teman terbaik Anda dalam hal mengimplementasikan emoji. Saya menemukan bahwa meskipun ya itu hanya unicode, itu cara Anda mengkodekan identifikasi rentang emoji dan pengaturan rentang emoji di situlah biaya kinerja Anda masuk Hati-hati menggunakan Perpustakaan emoji orang lain jika Anda tidak tahu bagaimana mereka berfungsi ...
JamisonMan111
45

Tali

A Stringtidak dapat diubah (yaitu, teks tidak dapat diubah). Itu juga tidak memiliki span yang terkait dengannya. (Span adalah rentang di atas teks yang menyertakan informasi gaya seperti warna, sorotan, miring, tautan, dll.) Jadi, Anda dapat menggunakan a Stringsaat teks Anda tidak perlu diubah dan tidak memerlukan gaya apa pun.

StringBuilder

A StringBuildermemiliki teks yang bisa berubah, jadi Anda bisa memodifikasinya tanpa membuat objek baru. Namun, itu tidak memiliki informasi rentang apa pun. Itu hanya teks biasa. Jadi gunakan StringBuildersaat Anda perlu mengubah teks, tetapi Anda tidak peduli tentang menatanya.

SpannedString

A SpannedStringmemiliki teks yang tidak dapat diubah (seperti a String) dan informasi rentang yang tidak dapat diubah. Ini adalah implementasi konkret dari persyaratan yang ditentukan oleh Spannedantarmuka. Gunakan a SpannedStringketika teks Anda memiliki gaya tetapi Anda tidak perlu mengubah teks atau gaya setelah itu dibuat.

Catatan: Tidak ada yang namanya SpannedStringBuilderkarena jika teks berubah maka informasi span kemungkinan besar juga harus berubah.

SpannableString

A SpannableStringmemiliki teks yang tidak dapat diubah, tetapi informasi span-nya dapat berubah. Ini adalah implementasi konkret dari persyaratan yang ditentukan oleh Spannableantarmuka. Gunakan a SpannableStringketika teks Anda tidak perlu diubah tetapi gaya perlu diubah.

SpannableStringBuilder

A SpannableStringBuildermemiliki teks yang bisa berubah dan informasi span. Ini adalah implementasi konkret dari persyaratan yang ditentukan oleh antarmuka Spannabledan Editable(antara lain). Gunakan SpannableStringBuildersaat Anda perlu memperbarui teks dan gayanya.

CharSequence

A CharSequenceadalah antarmuka dan bukan kelas konkret. Itu berarti itu hanya mendefinisikan daftar aturan yang harus diikuti untuk setiap kelas yang mengimplementasikannya. Dan semua kelas yang disebutkan di atas menerapkannya. Jadi, Anda dapat menggunakan a CharSequenceketika Anda ingin menggeneralisasi jenis objek yang Anda miliki untuk fleksibilitas maksimum. Anda selalu dapat menurunkannya menjadi Stringatau SpannableStringBuilderatau apa pun nanti jika perlu.

Suragch
sumber
4
Saya menghargai cara Anda menyampaikan tanggapan Anda, sangat mudah dibaca dan dipahami, terima kasih
JamisonMan111