Android Spanned, SpannedString, Spannable, SpannableString и CharSequence

96

Android предлагает различные интерфейсы все связанные с текстом и строками: Spanned, SpannedString, Spannable, SpannableStringи CharSequence.

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

Я попытался понять назначение / использование этих интерфейсов из официальной документации Android, но у меня ничего не вышло, так как это довольно запутанно. Какова цель этих интерфейсов? в каких сценариях они чаще всего используются? В каких случаях лучше избегать их использования? Есть ли какие-либо очевидные влияния на производительность при использовании любого из них?

Если бы кто-нибудь мог дать достойное объяснение, это было бы очень полезно.

Woot
источник

Ответы:

149

Какова цель этих интерфейсов?

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

Spanned- это CharSequenceс «промежутками», указывающими на форматирование, применяемое к частям текста, где эти промежутки не могут быть изменены.

Spannable- это Spannedдобавление возможности изменять промежутки (для добавления или удаления форматирования), но не для изменения самого текста.

SpannedStringэто конкретная реализация Spannedинтерфейса.

SpannableStringэто конкретная реализация Spannableинтерфейса.

в каких сценариях они чаще всего используются?

Когда есть метод, который возвращает один (например, getText()в a EditText), или когда есть метод, который принимает его в качестве параметра (например, setText()в a TextView). диаграмма из yuml.me/edit/35c8f39f

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

В каких случаях лучше избегать их использования?

Они особенно ужасны при борьбе с облысением, уборкой снега, ремонтом тепловых насосов, приготовлением суфле и т. Д.

:-)

Есть ли какие-либо очевидные влияния на производительность при использовании любого из них?

Интерфейсы по определению не оказывают «влияния на производительность» - они просто описание API.

Я не знаю, что SpannableStringэто значительно медленнее, чем SpannedStringпри любой конкретной операции. Однако SpannableStringBuilder(что позволяет манипулировать текстом в дополнение к диапазонам, которые форматируют этот текст) вполне может быть немного медленнее, чем SpannableStringили SpannedStringдля различных вещей. Однако будет ли разница в производительности иметь значение, будет зависеть от использования.

CommonsWare
источник
4
Поскольку официальная документация молчит, откуда вы взяли эту информацию? Ручной просмотр исходного кода хардкорным способом?
Pacerier
11
@Pacerier: Я не уверен, о какой части этого ответа вы говорите. Например, иерархия классов, описанная в этом ответе, наверняка взята из документации, в частности JavaDocs. И наоборот, бесполезность этих средств для борьбы с облысением объясняется личными наблюдениями.
CommonsWare
@CommonsWare, значит ли это, что строка со смайлами между ними будет считаться spannableStringнормальной, а не нормальной ... потому что я сталкиваюсь с огромной задержкой, setText(my_string) когда my_stringв ней есть смайлы (например, в watsapp) по сравнению с обычной строкой. . (в котором есть только простой текст), пожалуйста, пролейте свет ... почему-то я считал, что смайлы - это не что иное, как текст (unicode)
eRaisedToX 05
1
@eRaisedToX: Смайлы могут быть реализованы как смайлы или изображения. AFAIK, смайлики будут отдельными символами Unicode и, предположительно, могут быть в обычной строке. Изображения потребуют, ImageSpanчто, в свою очередь, требует SpannableString.
CommonsWare 05
Наверное, конечно ... но попробуйте разобраться с смайликами и использовать обычные строки, и вы сразу же вернетесь к борьбе с облысением. Editables и SpannableStringBuilders - ваши лучшие друзья, когда дело доходит до реализации эмодзи. Я обнаружил, что, хотя да, они просто юникод, это то, как вы кодируете определение диапазона эмодзи и настройку диапазона эмодзи, на который влияет ваша производительность. Будьте осторожны, используя библиотеки эмодзи других людей, если вы не знаете как они функционируют ...
JamisonMan111 08
45

Строка

A Stringнеизменяемо (т.е. текст не может измениться). Он также не имеет связанных с ним промежутков. (Промежутки - это диапазоны по тексту, которые включают информацию о стилях, такую ​​как цвет, выделение, курсив, ссылки и т. Д.). Таким образом, вы можете использовать, Stringкогда ваш текст не нужно изменять и не требует стилизации.

StringBuilder

A StringBuilderимеет изменяемый текст, поэтому вы можете изменить его, не создавая новый объект. Однако у него нет никакой информации о диапазоне. Это просто текст. Поэтому используйте, StringBuilderкогда вам нужно изменить текст, но вам не нужно его стилизовать.

SpannedString

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

Примечание. Не существует такой вещи, как a, SpannedStringBuilderпотому что, если текст изменится, вероятно, также придется изменить информацию о диапазоне.

SpannableString

A SpannableStringимеет неизменяемый текст, но его информация о диапазоне может изменяться. Это конкретная реализация требований, определенных Spannableинтерфейсом. Используйте, SpannableStringкогда ваш текст не нужно изменять, но стиль нужно.

SpannableStringBuilder

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

CharSequence

A CharSequence- это интерфейс, а не конкретный класс. Это означает, что он просто определяет список правил, которым нужно следовать для любого класса, который его реализует. И все упомянутые выше классы реализуют это. Таким образом, вы можете использовать, CharSequenceкогда хотите обобщить тип объекта, который у вас есть, для максимальной гибкости. Вы всегда можете понизить его до Stringили SpannableStringBuilderили чего-то еще, если вам нужно.

Suragch
источник
4
Я ценю то, как вы представили свой ответ, очень легко читать и понимать, спасибо
JamisonMan111 08