SpannableString: ano ito, mga klase ng estilo at kung paano ito gumagana

May-akda: IT Sectr Nai-publish: 2026-07-23 Oras ng pagbabasa: 10 min

SpannableString ay isang klase ng Android SDK mula sa paketeng android.text na nagpapahintulot sa paglalapat ng maramihang estilo sa iba't ibang bahagi ng isang string ng teksto sa TextView. Hindi tulad ng HTML markup, ang SpannableString ay gumagana sa antas ng mga bagay na Span, na namamahala sa visual na pagpapakita ng teksto: kulay, laki, tipo ng letra, salungguhit at mga interactive na elemento. Ayon sa Google Developers, ginagamit ang SpannableString sa mga bahagi ng sistema ng Android para sa pag-format ng mga link. Ito ang pangunahing paraan ng pag-istilo ng teksto nang hindi kumokonekta sa mga third-party na library.

Pangunahin

  • SpannableString — klase ng Android para sa pag-istilo ng teksto sa pamamagitan ng mga bagay na Span, hindi nababago pagkatapos gawin
  • Mga Span ay nahahati sa CharacterStyle (mga indibidwal na karakter) at ParagraphStyle (buong talata)
  • ForegroundColorSpan nagbabago ng kulay ng teksto, ang StyleSpan ay responsable para sa bold at italic
  • SpannableStringBuilder — nababagong bersyon para sa dinamikong pagbuo ng teksto na may suporta sa Editable
  • Span flags tinutukoy ang pag-uugali ng span kapag naglalagay at nagtatanggal ng teksto sa mga hangganan ng saklaw

Ano ang SpannableString?

SpannableString ay isang klase ng Android na nagpapatupad ng interface ng Spannable, na nag-iimbak ng teksto kasama ng isang set ng mga bagay na Span na namamahala sa visual na pagpapakita. Hindi tulad ng ordinaryong String, pinapayagan ng SpannableString ang pag-attach ng mga katangian ng estilo sa mga tiyak na saklaw ng mga karakter: gawing pula ang bahagi ng teksto, palakihin ang font sa pamagat, o magdagdag ng naki-click na link sa loob ng talata.

Ang klase ay nasa paketeng android.text at magagamit mula sa API Level 1. Ang SpannableString ay hindi nababago — pagkatapos gawin, ang istraktura nito ay naayos, at ang pagpapalit ng teksto ay nangangailangan ng paglikha ng bagong bagay. Para sa dinamikong pag-edit, ginagamit ang SpannableStringBuilder, na sumusuporta sa pagpasok at pagtanggal ng mga karakter nang hindi nawawala ang mga estilo.

Pagkakaiba sa CharSequence

CharSequence ay ang pangunahing interface para sa data ng teksto, na ipinatupad ng String, StringBuilder at SpannableString. Ang pangunahing pagkakaiba sa pagitan ng SpannableString at String ay ang suporta para sa pag-attach ng mga arbitraryong bagay sa substring. Nakikilala ng TextView ang interface ng Spannable at sa pag-render ay inilalapat ang mga bagay na span sa mga kaukulang bahagi ng teksto. Kung ang ordinaryong String ay ipinasa sa TextView, walang estilo ang ilalapat.

Panloob na Istraktura

Ang SpannableString ay nag-iimbak ng teksto bilang isang array na char[] at isang hiwalay na array ng mga bagay na span na may metadata tungkol sa simula at wakas na posisyon. Kapag tinawag ang setSpan(what, start, end, flags), ang bagay na what ay nai-save sa listahan kasama ng impormasyon tungkol sa saklaw. Sa pag-render, sunud-sunod na inilalapat ng TextView ang lahat ng span na nasa loob ng ipinapakitang saklaw, na tinatawag ang mga pamamaraang updateDrawState at updateMeasureState.

Mga Uri ng Span: CharacterStyle at ParagraphStyle

CharacterStyle ay ang base class para sa mga span na nakakaapekto sa mga indibidwal na karakter anuman ang kanilang posisyon sa mga linya. Kasama rito ang ForegroundColorSpan (kulay ng teksto), RelativeSizeSpan (kamag-anak na laki), StyleSpan (bold at italic), UnderlineSpan (salungguhit) at iba pa. Inilalapat ang Character-span sa bawat karakter sa tinukoy na saklaw nang isa-isa.

ParagraphStyle ay ang interface para sa mga span na nakakaapekto sa buong talata. Ang pinakakilalang kinatawan ay ang AlignmentSpan, na nag-aayos ng buong talata sa kaliwa, gitna o kanan. Dapat saklawin ng Paragraph-span ang buong talata, kung hindi, binabalewala ng Android ang paglalapat nito. Ang paghihigpit na ito ay nauugnay sa katotohanan na ang pagkakahanay o indentation ay may katuturan lamang para sa isang buong bloke ng teksto.

Span flags

Span flags ay apat na constant na tumutukoy sa pag-uugali ng span kapag naglalagay o nagtatanggal ng teksto sa mga hangganan ng saklaw nito. Pinapanatili ng SPAN_EXCLUSIVE_EXCLUSIVE na aktibo ang span lamang sa loob ng orihinal na mga hangganan, pinalalawak ito ng SPAN_INCLUSIVE_INCLUSIVE kapag nagdaragdag ng teksto sa mga hangganan. Ang SPAN_EXCLUSIVE_INCLUSIVE at SPAN_INCLUSIVE_EXCLUSIVE ay nagbibigay ng pinaghalong pag-uugali para sa simula at wakas ng saklaw.

FlagInsert KaliwaInsert Kanan
SPAN_EXCLUSIVE_EXCLUSIVEhindi kasamahindi kasama
SPAN_INCLUSIVE_INCLUSIVEkasamakasama
SPAN_EXCLUSIVE_INCLUSIVEhindi kasamakasama
SPAN_INCLUSIVE_EXCLUSIVEkasamahindi kasama

Ang tamang pagpili ng flag ay kritikal para sa Editable na teksto sa EditText, kung saan ang user ay maaaring magpasok at magtanggal ng mga karakter. Para sa read-only na TextView karaniwang ginagamit ang SPAN_EXCLUSIVE_EXCLUSIVE — ang estilo ay inilalapat lamang sa orihinal na saklaw at hindi lumalawak sa mga pagbabagong programmatic.

Mga Pangunahing Klase ng Span sa Android SDK

Ang Android SDK ay nagbibigay ng higit sa 25 built-in na klase ng span na sumasaklaw sa karamihan ng mga gawain sa pag-istilo ng teksto. Bawat klase ay nagpapatupad ng interface ng CharacterStyle o ParagraphStyle at tumatanggap ng mga parameter sa pamamagitan ng constructor. Lahat ng klase ay nasa paketeng android.text.style at magagamit nang hindi kumokonekta ng mga karagdagang dependency.

Mga Span para sa Kulay at Background

ForegroundColorSpan nagtatakda ng kulay ng teksto para sa tinukoy na saklaw, tumatanggap ng kulay sa format na int. Kinulayan ng BackgroundColorSpan ang background sa ilalim ng teksto, kapaki-pakinabang para sa pag-highlight ng mga query sa paghahanap. Itinatakda ng AbsoluteSizeSpan ang eksaktong laki ng font sa mga pixel, RelativeSizeSpan — isang multiplier na may kaugnayan sa base na laki ng teksto sa TextView.

Mga Span para sa Estilo ng Letra

StyleSpan tumatanggap ng mga constant na Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC o BOLD_ITALIC at binabago ang anyo ng mga karakter. Nagdaragdag ang UnderlineSpan ng salungguhit, StrikethroughSpan — strikethrough. Ang SuperscriptSpan at SubscriptSpan ay lumilikha ng superscript at subscript. Pinapayagan ng TypefaceSpan ang pagtatakda ng custom na font sa pamamagitan ng bagay na Typeface para sa isang saklaw ng teksto.

Mga Interactive na Span

ClickableSpan ay isang abstract class para sa paglikha ng mga naki-click na bahagi ng teksto. Kapag pinindot, tinatawag ang pamamaraang onClick(). Para gumana ang mga click, ang TextView ay dapat may setMovementMethod(LinkMovementMethod.getInstance()). Ang URLSpan ay isang subclass ng ClickableSpan para sa mga hyperlink na may awtomatikong pagbubukas ng browser. Ang ClickableSpan ay madalas na pinagsama sa ForegroundColorSpan upang biswal na i-highlight ang link na may asul na kulay.

kotlin
val spannable = SpannableString("Open developer.android.com")
spannable.setSpan(
    URLSpan("https://developer.android.com"),
    9, 31, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
spannable.setSpan(
    ForegroundColorSpan(Color.BLUE),
    9, 31, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannable
textView.movementMethod = LinkMovementMethod.getInstance()

Kung wala ang LinkMovementMethod, ang mga click sa URLSpan ay hindi mapoproseso. Ang MovementMethod ay responsable para sa pagharang ng mga touch event at paghahanap ng ClickableSpan sa posisyon ng pagpindot. Ang may kulay na span ay ginagawang nakikita ang link para sa user.

Paano Gamitin ang SpannableString sa Kodigo

Ang pagtatrabaho sa SpannableString ay nagsisimula sa paglikha ng isang instance mula sa isang string ng teksto at sunud-sunod na paglalapat ng mga span sa pamamagitan ng pamamaraang setSpan(). Ang pamamaraan ay tumatanggap ng apat na parameter: ang bagay na span, posisyon ng simula, posisyon ng wakas, at mga flag. Pagkatapos itakda ang lahat ng span, ang bagay ay ipinapasa sa TextView sa pamamagitan ng setText().

Kulay at Laki ng Teksto

Gagawa tayo ng string kung saan ang unang salita ay magiging pula at mas malaki ang laki. Para dito ginagamit ang ForegroundColorSpan para sa kulay at RelativeSizeSpan para sa scale. Ang parehong span ay inilalapat sa parehong saklaw nang hiwalay sa isa't isa — ang pagkakasunud-sunod ng pagtawag sa setSpan ay hindi mahalaga.

kotlin
val text = "Header: remaining text"
val spannable = SpannableString(text)
val colorSpan = ForegroundColorSpan(Color.RED)
val sizeSpan = RelativeSizeSpan(1.5f)
spannable.setSpan(colorSpan, 0, 9, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
spannable.setSpan(sizeSpan, 0, 9, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = spannable

Ang mga karakter mula sa posisyon 0 hanggang 9 ay makakatanggap ng parehong estilo nang sabay. Awtomatikong inilalapat ng TextView ang lahat ng span sa pag-render — walang karagdagang tawag ang kinakailangan. Ang RelativeSizeSpan na may multiplier na 1.5f ay magpapalaki ng laki ng font ng 50% kumpara sa base.

Pagsasama-sama sa mga HTML Tag

Html.fromHtml() ay lumilikha ng isang bagay na Spanned mula sa isang HTML string, ngunit ang hanay ng mga suportadong tag ay limitado. Ang SpannableString ay nagbibigay ng buong kontrol sa bawat atributo nang walang mga limitasyon ng HTML. Kung kinakailangan i-convert ang HTML sa mga span na may kasunod na pagdaragdag ng mga custom na estilo, maaaring gamitin ang Html.fromHtml() bilang batayan, pagkatapos ay dagdagan ng mga span sa pamamagitan ng setSpan().

kotlin
val htmlText = Html.fromHtml(
    "<b>Important:</b> check the data",
    Html.FROM_HTML_MODE_LEGACY
)
val spannable = SpannableString(htmlText)
spannable.setSpan(
    ForegroundColorSpan(Color.RED),
    0, 6, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannable

Ang resulta — ang tekstong "Mahalaga:" ay magiging bold (mula sa HTML) at pula (mula sa span). Ang ganitong paraan ay maginhawa kapag nagtatrabaho sa nilalaman ng server, kung saan ang bahagi ng pag-format ay itinakda sa pamamagitan ng HTML, at ang bahagi ay idinaragdag nang programmatic sa panig ng kliyente.

Pagsasama-sama ng Maramihang Span

Pinapayagan ng SpannableString ang paglalapat ng walang limitasyong bilang ng span sa pareho o magkakapatong na saklaw. Ang pagsasama-sama ng mga span ay isang pangunahing bentahe kumpara sa HTML markup, kung saan ang mga nested tag ay maaaring magkasalungat. Ang mga span ay independyente at inilalapat nang sunud-sunod sa pag-render.

Halimbawa, ang isang bahagi ng teksto ay maaaring gawing sabay-sabay na bold, pula at naki-click. Para dito, tatlong span ang ginawa — StyleSpan, ForegroundColorSpan at ClickableSpan — at bawat isa ay inilalapat sa parehong saklaw. Ang pagkakasunud-sunod ng paglalapat ay hindi nakakaapekto sa resulta, dahil ang bawat span ay responsable para sa sarili nitong katangian ng teksto.

Pagpapatong ng mga Span ng Iba't Ibang Uri

Kung ang mga span ng iba't ibang uri ay bahagyang nagpapatong, bawat isa ay gumagana nang hiwalay sa sarili nitong mga hangganan. ForegroundColorSpan sa saklaw na 0-10 at StyleSpan(BOLD) sa saklaw na 5-15 ay magbibigay ng pulang bold na teksto sa bahaging 5-10 at bold lamang sa 10-15. Walang lumalabas na salungatan, dahil binabago ng bawat span ang sarili nitong atributo sa pag-render.

Pagkuha ng Listahan ng mga Span

Ang pamamaraang getSpans(int start, int end, Class type) ay nagbabalik ng array ng mga span na nasa loob ng tinukoy na saklaw. Ito ay kapaki-pakinabang para sa pagsusuri kung aling mga estilo ang nailapat na o para sa pagtanggal ng mga partikular na span. Gamit ang nextSpanTransition() maaaring mag-iterate sa mga hangganan ng pagbabago ng span — ito ang batayan ng paggana ng mga custom na TextView na kailangang malaman kung saan nagbabago ang estilo.

SpannableStringBuilder para sa Pagbuo ng Teksto

SpannableStringBuilder ay isang klase para sa hakbang-hakbang na pagbuo ng naka-istilong teksto na may kakayahang magpasok, magpalit at magtanggal ng mga fragment. Hindi tulad ng SpannableString, na ginawa mula sa isang handa na string at hindi nababago, pinapayagan ng Builder ang sunud-sunod na pagdaragdag ng mga bahagi ng teksto at pagtatalaga ng mga estilo sa daan. Ito ang perpektong pagpipilian para sa mga pinagsamang mensahe: mga log, chat, headline ng balita na may mga dynamic na label.

Ipinapatupad ng Builder ang mga interface na Spannable at Editable, na ginagawa itong katugma sa EditText. Maaaring i-edit ng user ang teksto, at ang mga estilo ay pinapanatili at tamang lumilipat kapag nagpapasok ng mga bagong karakter. Ang SpannableString, dahil hindi nababago, ay hindi angkop para sa mga editable field.

Kadena ng mga Operasyon

Ang pamamaraang append() ay nagbabalik ng builder mismo, na nagpapahintulot sa pagbuo ng isang kadena ng mga tawag. Pagkatapos magdagdag ng teksto, inilalapat ang mga span sa pamamagitan ng setSpan(). Ang mga posisyon ay ipinapahiwatig na may kaugnayan sa kasalukuyang haba ng builder. Ang Insert() at replace() ay magagamit din para sa mas tumpak na kontrol sa nilalaman.

kotlin
val builder = SpannableStringBuilder()
    .append("New ")
    .append("comment")
val blue = ForegroundColorSpan(Color.BLUE)
val gray = ForegroundColorSpan(Color.GRAY)
builder.setSpan(blue, 0, 6, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
builder.setSpan(gray, 6, 17, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = builder

Ang tekstong "Bago " ay may kulay asul, at ang "komento" ay may kulay abo. Kapag nagpapasok ng mga karagdagang karakter sa pagitan nila, hindi maaapektuhan ng span ang bagong teksto dahil sa mga flag na EXCLUSIVE. Awtomatikong itinatama ng Builder ang mga panloob na index kapag nagbago.

Pagganap at Pag-optimize ng Span

Ang paggamit ng maraming bilang ng span ay nakakaapekto sa pagganap ng pag-render ng TextView. Bawat span ay tumatawag sa pamamaraang updateDrawState() o updateMeasureState() sa bawat muling pag-render. Inirerekomenda na limitahan ang bilang ng span bawat TextView sa 50–100 para sa komportableng trabaho sa mga mid-segment na device. Ang mga span na nagbabago ng laki ng teksto (RelativeSizeSpan, AbsoluteSizeSpan) ay nangangailangan ng muling pagkalkula ng layout sa bawat pagbabago, na mas mahal kaysa sa mga span para lamang sa kulay o salungguhit.

TextAppearanceSpan

TextAppearanceSpan ay nagpapahintulot sa paglalapat ng isang buong hanay ng mga estilo mula sa xml resource na android:textAppearance sa isang operasyong setSpan(). Sa halip na tatlong hiwalay na span (kulay, laki, font) ginagamit ang isang TextAppearanceSpan na may reference sa estilo. Binabawasan nito ang bilang ng mga bagay at pinapasimple ang pagpapanatili — ang pagbabago ng estilo sa resource ay awtomatikong inilalapat sa lahat ng teksto na gumagamit ng span na ito.

Paggamit Muli ng mga Bagay

Ang paglikha ng bagong instance ng span para sa bawat setSpan() ay nagdudulot ng karagdagang load sa garbage collector. Optimal na gumawa ng constant na bagay ng span kung paulit-ulit na inilalapat. Halimbawa, ang ForegroundColorSpan(Color.RED) ay maaaring i-save sa companion object at muling gamitin. Gayunpaman, ang mga span na may estado (ClickableSpan na may iba't ibang handler) ay dapat gawin nang isa-isa para sa bawat kaso.

Pagsukat at Profiling

Para sa pag-diagnose ng mga problema sa pagganap ng span, gamitin ang Layout Inspector sa Android Studio at GPU profiler. Kung ang TextView na may maraming span ay kapansin-pansing bumagal sa pag-scroll, isaalang-alang ang pagpapalit ng bahagi ng span ng mga static na estilo sa pamamagitan ng TextAppearanceSpan o pagbawas ng bilang ng span sa pamamagitan ng pagsasama-sama ng mga atributo sa custom na pagpapatupad ng UpdateAppearance.

Mga Madalas Itanong

Paano naiiba ang SpannableString sa ordinaryong String?

String ay isang hindi nababagong pagkakasunod-sunod ng mga karakter na walang suporta sa estilo. Ang SpannableString ay nag-iimbak ng parehong mga karakter, ngunit karagdagang naglalaman ng isang array ng mga bagay na Span na may impormasyon sa pag-format. Tinutukoy ng TextView ang uri ng ipinasa na CharSequence at inilalapat ang mga span sa mga kaukulang saklaw sa pag-render. Binabalewala ng String ang anumang mga katangian ng estilo at ipinapakita bilang plain text.

Paano tanggalin ang lahat ng span mula sa SpannableString?

Ang pamamaraang removeSpan(Object span) ay nagtatanggal ng isang partikular na span. Para sa kumpletong paglilinis, tawagan ang getSpans(0, length, Object::class.java), na nagbabalik ng array ng lahat ng span, at pagkatapos ay tanggalin ang bawat isa sa pamamagitan ng removeSpan. Bilang kahalili, gumawa ng bagong SpannableString(text.toString()) na walang span. Ang SpannableStringBuilder ay may pamamaraang clear() na nagtatanggal ng parehong teksto at span.

Gumagana ba ang SpannableString sa EditText?

SpannableString ay gumagana sa EditText, ngunit para sa nai-edit na teksto mas mainam ang SpannableStringBuilder na nagpapatupad ng Editable. Ang EditText ay nangangailangan ng Editable interface para sa pagsubaybay sa mga pagbabago. Kung ang SpannableString ay ipinasa sa EditText, ang teksto ay ipapakita na may mga estilo, ngunit sa pag-edit, iko-convert ito ng Android sa Editable, na maaaring mag-reset ng ilang span.

Maaari bang gamitin ang SpannableString sa Compose?

Sa Jetpack Compose, ang mga Android SDK span ay hindi direktang ginagamit. Sa halip, ang Compose ay nagbibigay ng AnnotatedString — sarili nitong katumbas ng SpannableString na may katulad na kakayahan: SpanStyle para sa mga estilo ng indibidwal na karakter at ParagraphStyle para sa mga talata. Ang conversion ng SpannableString sa AnnotatedString ay posible sa pamamagitan ng buildAnnotatedString na may iteration sa mga span.

Paano gumawa ng custom na Span?

Gumawa ng klase na nagmamana mula sa CharacterStyle at i-override ang pamamaraang updateDrawState(TextPaint tp). Sa loob ng pamamaraan, baguhin ang mga katangian ng TextPaint: kulay, kapal ng linya, mga epekto. Para sa metric na pagbabago gamitin ang UpdateLayout o MetricAffectingSpan. Ang mga custom na span ay inilalapat sa pamamagitan ng setSpan() tulad ng mga built-in na span.

Buod

  • SpannableString — klase ng Android para sa pag-istilo ng teksto sa pamamagitan ng mga bagay na Span na may pag-attach sa mga saklaw ng karakter
  • CharacterStyle ay nakakaapekto sa mga indibidwal na karakter, ParagraphStyle — buong talata
  • Mga pangunahing span: ForegroundColorSpan, StyleSpan, RelativeSizeSpan, URLSpan, ClickableSpan
  • SpannableStringBuilder — nababagong bersyon para sa dinamikong pagbuo ng teksto na may Editable
  • Pagsasama-sama ng mga span ay ligtas — bawat span ay nagbabago ng sarili nitong atributo nang hiwalay
  • Span flags namamahala sa pag-uugali ng span kapag nagpapasok ng teksto sa mga hangganan
  • Pag-optimize: gamitin ang TextAppearanceSpan para sa mga grupo ng estilo at limitahan ang bilang ng span sa 100

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din