Android Spanned, SpannedString, Spannable, SpannableString і CharSequence


92

Android пропонує різні інтерфейси все пов'язані з текстом і рядками: Spanned, SpannedString, Spannable, SpannableStringі CharSequence.

Я використовував усе вищезазначене в різних сценаріях, як правило, після того, як використовував Html.fromHtml()для відображення пов’язуваного тексту всередині TextView, щоб застосувати до нього деякий стиль.

Я спробував зрозуміти призначення / використання цих інтерфейсів з офіційної документації Android і зазнав невдачі, оскільки це досить заплутано .. Яке призначення цих інтерфейсів? в яких сценаріях найчастіше їх використовують? У яких випадках краще уникати їх використання? Чи є явні наслідки для продуктивності, які слід враховувати при використанні будь-якого з них?

Якби хтось міг дати гідне пояснення, це було б дуже вдячне.

Відповіді:


148

Яке призначення цих інтерфейсів?

діаграма з yuml.me/edit/5f8da6cb CharSequence- це стандартний інтерфейс Java, що представляє послідовність символів. Stringє найбільш часто використовуваною конкретною реалізацією CharSequence, а потім -StringBuilder .

Spanned це CharSequence "з розмахом", що вказує форматування, яке застосовується до частин тексту, де ці проміжки не можуть бути змінені.

Spannableє Spanned, додаючи можливість модифікувати інтервали (додати або видалити форматування), але не змінювати сам текст.

SpannedStringє конкретною реалізацією Spannedінтерфейсу.

SpannableStringє конкретною реалізацією Spannableінтерфейсу.

в яких сценаріях в основному їх використовують?

Коли існує метод, який повертає один (наприклад, getText()на an EditText), або коли існує метод, який приймає один як параметр (наприклад, setText()на a TextView). діаграма з yuml.me/edit/35c8f39f

Ваш цитований випадок використання Html.fromHtml(), мабуть, найпоширеніший у звичайній розробці Android, оскільки a TextViewз Spannedнабагато легшим за вагою, ніж a WebView. Однак є й інші випадки використання, такі як:

У яких випадках краще уникати їх використання?

Вони особливо жахливі в боротьбі з облисінням, видаленням снігу, ремонтом теплового насоса, виготовленням суфле тощо.

:-)

Чи є явні наслідки для продуктивності, які слід враховувати при використанні будь-якого з них?

Інтерфейси, за визначенням, не мають "впливу на продуктивність" - вони є лише описом API.

Я не знаю, що SpannableStringце значно повільніше, ніж SpannedStringпри будь-якій конкретній операції. Тим НЕ менше, SpannableStringBuilder(що дозволяє маніпулювати текст в доповненні до прольотах , що формат, текст) може також бути трохи повільніше , ніж SpannableStringабо SpannedStringдля різних речей. Чи достатньо різниці в продуктивності для того, щоб мати значення, залежатиме від використання.


4
Оскільки офіційні документи мовчать, як ви взяли цю інформацію? Перегляд джерела вручну хардкорним способом?
Pacerier

11
@Pacerier: Я не впевнений, на яку частину цієї відповіді ви посилаєтесь. Наприклад, описана в цій відповіді ієрархія класів, безперечно, походить із документації, зокрема JavaDocs. І навпаки, відсутність корисності цих речей для боротьби з облисінням походить від особистого спостереження.
CommonsWare

@CommonsWare, так це означає, що рядок із смайликами між ними вважатиметься spannableStringзвичайним, а не звичайним .. тому що я стикаюся з величезним відставанням, setText(my_string) коли my_stringв ньому є смайли (як у watsapp) порівняно із звичайним рядком. . (який має лише простий текст) ласкаво проливайте трохи світла ... якимось чином я повірив, що smilleys - це не що інше, як текст (Unicode)
eRaisedToX

1
@eRaisedToX: Смайли можна реалізувати як смайлики або зображення. AFAIK, смайли будуть окремими символами Unicode і, мабуть, можуть бути у звичайному рядку. Зображення потребують того, ImageSpanщо, в свою чергу, вимагає SpannableString.
CommonsWare

Імовірно, впевнений ... але спробуйте мати справу із смайликами та використовувати звичайні струни, і ви повернетесь до боротьби з облисінням. Editables та SpannableStringBuilders - ваш найкращий друг, коли справа доходить до реалізації смайликів. Я виявив, що, хоча так, вони просто unicode, це те, як ви кодуєте ідентифікацію діапазону смайлів та налаштування діапазону смайликів, саме там витрачається ваша продуктивність. Будьте обережні, використовуючи чужі бібліотеки емодзі, якщо ви не знаєте як вони функціонують ...
JamisonMan111

43

Рядок

A Stringнезмінна (тобто текст не може змінюватися). Він також не має жодних проміжків, пов’язаних з ним. (Прольоти - це діапазони тексту, які включають інформацію про стиль, наприклад, колір, виділення, курсив, посилання тощо.) Таким чином, ви можете використовувати символ, Stringколи текст не потрібно змінювати і не потребує стилю.

StringBuilder

A StringBuilderмає змінний текст, тому ви можете змінити його, не створюючи новий об’єкт. Однак він не має жодної інформації про проміжок часу. Це просто текст. Тож використовуйте a, StringBuilderколи вам потрібно змінити текст, але ви не дбаєте про його стиль.

SpannedString

A SpannedStringмає незмінний текст (наприклад, a String) та незмінну інформацію про проміжок часу. Це конкретна реалізація вимог, визначених Spannedінтерфейсом. Використовуйте, SpannedStringколи ваш текст має стиль, але вам не потрібно змінювати ні текст, ні стиль після його створення.

Примітка: Не існує такого поняття, як, SpannedStringBuilderоскільки, якщо текст змінюється, тоді інформація про діапазон також, швидше за все, повинна буде змінитися.

SpannableString

A SpannableStringмає незмінний текст, але інформація про його діапазон змінюється. Це конкретна реалізація вимог, визначених Spannableінтерфейсом. Використовуйте, SpannableStringколи текст не потрібно змінювати, але стиль потрібно.

SpannableStringBuilder

A SpannableStringBuilderмає як змінний текст, так і інформацію про пробіг. Це конкретна реалізація вимог, визначених інтерфейсами Spannableта Editable(між іншим). Використовуйте, SpannableStringBuilderколи вам потрібно буде оновити текст та його стиль.

CharSequence

A CharSequence- це інтерфейс, а не конкретний клас. Це означає, що він просто визначає перелік правил, яких слід дотримуватися для будь-якого класу, який його реалізує. І всі згадані вище класи реалізують це. Тож ви можете використовувати a, CharSequenceколи хочете узагальнити тип об’єкта, який у вас є, для максимальної гнучкості. Ви завжди можете знизити його до Stringабо, SpannableStringBuilderабо що завгодно пізніше, якщо вам потрібно.


3
Я вдячний за те, як ви подали свою відповідь, дуже легко читати та розуміти, дякую
JamisonMan111,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.