Android Spanned, SpannedString, Spannable, SpannableString и CharSequence

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

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

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

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

Ответ 1

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

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

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

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

SpannedString представляет собой конкретную реализацию интерфейса Spanned.

SpannableString представляет собой конкретную реализацию интерфейса Spannable.

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

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

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

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

Они необычайно ужасны в борьбе с облысением, удалением снега, ремонтом теплового насоса, изготовлением суфле и т.д.

: -)

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

Интерфейсы, по определению, не имеют "влияния на производительность" - это просто описание API.

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

Ответ 2

String

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

StringBuilder

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

SpannedString

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

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

SpannableString

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

SpannableStringBuilder

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

CharSequence

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