SpannableString: nima, uslub klasslari va qanday ishlaydi

Muallif: IT Sectr Nashr etilgan: 2026-07-23 O'qish vaqti: 10 daq

SpannableString — bu android.text paketidagi Android SDK sinfi bo‘lib, TextView-da bitta matn qatorining turli qismlariga bir nechta uslublarni qo‘llash imkonini beradi. HTML belgilashdan farqli o‘laroq, SpannableString Span obyektlari darajasida ishlaydi va matnning vizual ko‘rinishini boshqaradi: rang, o‘lcham, shrift, tagiga chizish va interaktiv elementlar. Google Developers ma’lumotlariga ko‘ra, SpannableString Android tizim komponentlarida havolalarni formatlash uchun ishlatiladi. Bu uchinchi tomon kutubxonalarini ulamasdan matnni uslublashning asosiy usulidir.

Asosiy

  • SpannableString — Span obyektlari orqali matnni uslublash uchun Android sinfi, yaratilgandan keyin o‘zgarmas
  • Spanlar CharacterStyle (alohida belgilar) va ParagraphStyle (butun paragraflar) ga bo‘linadi
  • ForegroundColorSpan matn rangini o‘zgartiradi, StyleSpan qalin va kursiv uchun javobgar
  • SpannableStringBuilder — Editable qo‘llab-quvvatlashi bilan matnni dinamik qurish uchun o‘zgartiriladigan versiya
  • Span bayroqlari diapazon chegaralarida matn kiritish va o‘chirishda spanning xatti-harakatini aniqlaydi

SpannableString nima?

SpannableString — bu Spannable interfeysini amalga oshiradigan Android sinfi bo‘lib, matnni vizual ko‘rinishni boshqaradigan Span obyektlari to‘plami bilan birga saqlaydi. Oddiy String dan farqli o‘laroq, SpannableString belgilarning ma’lum diapazonlariga uslub atributlarini biriktirish imkonini beradi: matnning bir qismini qizil qilish, sarlavhadagi shriftni kattalashtirish yoki paragraf ichiga bosiladigan havola qo‘shish.

Sinf android.text paketida joylashgan va API Level 1 dan boshlab mavjud. SpannableString o‘zgarmas — yaratilgandan so‘ng uning tuzilishi o‘rnatiladi va matnni almashtirish yangi obyekt yaratishni talab qiladi. Dinamik tahrirlash uchun uslublarni yo‘qotmasdan belgilarni kiritish va o‘chirishni qo‘llab-quvvatlaydigan SpannableStringBuilder ishlatiladi.

CharSequence dan farqi

CharSequence — bu String, StringBuilder va SpannableString tomonidan amalga oshiriladigan matn ma’lumotlari uchun asosiy interfeys. SpannableString va String o‘rtasidagi asosiy farq pastki qatorga ixtiyoriy obyektlarni biriktirishni qo‘llab-quvvatlashdadir. TextView Spannable interfeysini taniydi va chizish paytida span obyektlarini matnning tegishli qismlariga qo‘llaydi. Agar TextView ga oddiy String uzatilsa, hech qanday uslublar qo‘llanilmaydi.

Ichki tuzilma

SpannableString matnni char[] massivi va boshlang‘ich va tugash pozitsiyasi haqidagi metama’lumotlarga ega span obyektlarining alohida massivi sifatida saqlaydi. setSpan(what, start, end, flags) chaqirilganda, what obyekti diapazon haqidagi ma’lumot bilan birga ro‘yxatga saqlanadi. Chizish paytida TextView ko‘rsatilgan diapazonga tushadigan barcha spanlarni ketma-ket qo‘llaydi va updateDrawState va updateMeasureState metodlarini chaqiradi.

Span turlari: CharacterStyle va ParagraphStyle

CharacterStyle — bu qatorlardagi joylashuvidan qat‘i nazar, alohida belgilarga ta’sir qiladigan spanlar uchun asosiy sinf. Bularga ForegroundColorSpan (matn rangi), RelativeSizeSpan (nisbiy o‘lcham), StyleSpan (qalin va kursiv), UnderlineSpan (tagiga chizish) va boshqalar kiradi. Character-spanlar belgilangan diapazondagi har bir belgiga alohida qo‘llaniladi.

ParagraphStyle — bu butun paragraflarga ta’sir qiladigan spanlar uchun interfeys. Eng taniqli vakili AlignmentSpan bo‘lib, u butun paragrafni chapga, markazga yoki o‘ngga tenglashtiradi. Paragraph-spanlar butun paragrafni qamrab olishi kerak, aks holda Android ularni qo‘llashni e’tiborsiz qoldiradi. Bu cheklov tekislash yoki chekinish faqat butun matn bloki uchun mantiqiy ekanligi bilan bog‘liq.

Span bayroqlari

Span bayroqlari — bu diapazon chegaralarida matn kiritish yoki o‘chirishda spanning xatti-harakatini aniqlaydigan to‘rtta doimiy. SPAN_EXCLUSIVE_EXCLUSIVE spanni faqat asl chegaralar ichida faol saqlaydi, SPAN_INCLUSIVE_INCLUSIVE chegaralarga matn qo‘shilganda uni kengaytiradi. SPAN_EXCLUSIVE_INCLUSIVE va SPAN_INCLUSIVE_EXCLUSIVE diapazonning boshi va oxiri uchun aralash xatti-harakatni ta’minlaydi.

BayroqChapdan kiritishO‘ngdan kiritish
SPAN_EXCLUSIVE_EXCLUSIVEkiritmaydikiritmaydi
SPAN_INCLUSIVE_INCLUSIVEkiritadikiritadi
SPAN_EXCLUSIVE_INCLUSIVEkiritmaydikiritadi
SPAN_INCLUSIVE_EXCLUSIVEkiritadikiritmaydi

Bayroqni to‘g‘ri tanlash EditText dagi Editable matn uchun juda muhim, chunki foydalanuvchi belgilarni kiritishi va o‘chirishi mumkin. Faqat o‘qish uchun TextView uchun odatda SPAN_EXCLUSIVE_EXCLUSIVE ishlatiladi — uslub faqat asl diapazonga qo‘llaniladi va dasturiy o‘zgarishlar bilan kengaymaydi.

Android SDK-dagi asosiy span sinflari

Android SDK matnni uslublashning ko‘p vazifalarini qamrab oluvchi 25 dan ortiq o‘rnatilgan span sinflarini taqdim etadi. Har bir sinf CharacterStyle yoki ParagraphStyle interfeysini amalga oshiradi va konstruktor orqali parametrlarni qabul qiladi. Barcha sinflar android.text.style paketida joylashgan va qo‘shimcha bog‘liqliklarni ulamasdan mavjud.

Rang va fon uchun spanlar

ForegroundColorSpan belgilangan diapazon uchun matn rangini o‘rnatadi va rangni int formatida qabul qiladi. BackgroundColorSpan matn ostidagi fonni bo‘yaydi, bu qidiruv so‘rovlarini ajratib ko‘rsatish uchun foydali. AbsoluteSizeSpan shriftning aniq o‘lchamini piksellarda o‘rnatadi, RelativeSizeSpan — TextView dagi matnning asosiy o‘lchamiga nisbatan ko‘paytiruvchi.

Shrift ko‘rinishi uchun spanlar

StyleSpan Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC yoki BOLD_ITALIC doimiylarini qabul qiladi va belgilarning ko‘rinishini o‘zgartiradi. UnderlineSpan tagiga chizadi, StrikethroughSpan — chizib tashlaydi. SuperscriptSpan va SubscriptSpan yuqori va pastki indekslarni yaratadi. TypefaceSpan Typeface obyekti orqali matn diapazoni uchun maxsus shrift o‘rnatish imkonini beradi.

Interaktiv spanlar

ClickableSpan — matnning bosiladigan qismlarini yaratish uchun mavhum sinf. Bosilganda onClick() metodi chaqiriladi. Bosishlar ishlashi uchun TextView setMovementMethod(LinkMovementMethod.getInstance()) ga ega bo‘lishi kerak. URLSpan — brauzerni avtomatik ochish bilan giperhavolalar uchun ClickableSpan ning pastki sinfi. ClickableSpan ko‘pincha havolani ko‘k rang bilan vizual ajratib ko‘rsatish uchun ForegroundColorSpan bilan birlashtiriladi.

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()

LinkMovementMethod bo‘lmasa, URLSpan dagi bosishlar qayta ishlanmaydi. MovementMethod sensorli hodisalarni tutib olish va teginish joyida ClickableSpanni qidirish uchun javobgardir. Rangli span havolani foydalanuvchiga ko‘rinadigan qiladi.

SpannableString-ni kodda qanday ishlatish

SpannableString bilan ishlash matn qatoridan namuna yaratish va setSpan() metodi orqali spanlarni ketma-ket qo‘llash bilan boshlanadi. Metod to‘rtta parametrni qabul qiladi: span obyekti, boshlang‘ich pozitsiya, tugash pozitsiyasi va bayroqlar. Barcha spanlar o‘rnatilgandan so‘ng, obyekt setText() orqali TextView ga uzatiladi.

Matn rangi va o‘lchami

Birinchi so‘zi qizil va kattalashtirilgan o‘lchamda bo‘ladigan qator yaratamiz. Buning uchun rang uchun ForegroundColorSpan va masshtab uchun RelativeSizeSpan ishlatiladi. Ikkala span bir xil diapazonga bir-biridan mustaqil ravishda qo‘llaniladi — setSpan ni chaqirish tartibi muhim emas.

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

0 dan 9 gacha pozitsiyadagi belgilar ikkala uslubni bir vaqtning o‘zida oladi. TextView chizish paytida avtomatik ravishda barcha spanlarni qo‘llaydi — qo‘shimcha chaqiruvlar talab qilinmaydi. 1.5f ko‘paytiruvchisi bilan RelativeSizeSpan shrift o‘lchamini asosiyga nisbatan 50% ga oshiradi.

HTML teglari bilan birlashtirish

Html.fromHtml() HTML qatoridan Spanned obyektini yaratadi, ammo qo‘llab-quvvatlanadigan teglar to‘plami cheklangan. SpannableString HTML cheklovlarisiz har bir atribut ustidan to‘liq nazoratni ta’minlaydi. Agar HTMLni spanlarga aylantirish va keyin maxsus uslublar qo‘shish kerak bo‘lsa, Html.fromHtml() dan asos sifatida foydalanishingiz mumkin, so‘ngra setSpan() orqali spanlar bilan to‘ldirishingiz mumkin.

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

Natija — "Muhim:" matni (HTML dan) qalin va (spandan) qizil bo‘ladi. Bunday yondashuv server kontenti bilan ishlashda qulay, bunda formatlashning bir qismi HTML orqali o‘rnatiladi, bir qismi esa dasturiy ravishda mijoz tomonida qo‘shiladi.

Bir nechta spanni birlashtirish

SpannableString bir xil yoki bir-biriga yopishgan diapazonga cheksiz miqdordagi spanni qo‘llash imkonini beradi. Spanlarni birlashtirish HTML belgilashga nisbatan asosiy afzallikdir, chunki ichki teglar ziddiyatga kelishi mumkin. Spanlar mustaqil va chizish paytida ketma-ket qo‘llaniladi.

Masalan, matnning bir qismini bir vaqtning o‘zida qalin, qizil va bosiladigan qilish mumkin. Buning uchun uchta span — StyleSpan, ForegroundColorSpan va ClickableSpan — yaratiladi va har biri bir xil diapazonga qo‘llaniladi. Qo‘llash tartibi natijaga ta’sir qilmaydi, chunki har bir span matnning o‘z xususiyati uchun javobgardir.

Har xil turdagi spanlarning yopishishi

Agar har xil turdagi spanlar qisman yopishsa, har biri o‘z chegaralarida mustaqil ishlaydi. ForegroundColorSpan 0-10 diapazonida va StyleSpan(BOLD) 5-15 diapazonida 5-10 qismida qizil qalin matn va 10-15 qismida faqat qalin matn beradi. Hech qanday ziddiyat yuzaga kelmaydi, chunki har bir span chizish paytida o‘z atributini o‘zgartiradi.

Spanlar ro‘yxatini olish

getSpans(int start, int end, Class type) metodi belgilangan diapazonga tushadigan spanlar massivini qaytaradi. Bu qaysi uslublar qo‘llanilganligini tekshirish yoki ma’lum spanlarni o‘chirish uchun foydali. nextSpanTransition() bilan span o‘zgarish chegaralari bo‘ylab iteratsiya qilish mumkin — bu uslub qayerda o‘zgarishini bilishi kerak bo‘lgan maxsus TextView larning ishlash asosidir.

Matn qurish uchun SpannableStringBuilder

SpannableStringBuilder — bu qismlarni kiritish, almashtirish va o‘chirish imkoniyati bilan bosqichma-bosqich uslublangan matn qurish uchun sinf. Tayyor qatordan yaratilgan va o‘zgarmas bo‘lgan SpannableString dan farqli o‘laroq, Builder matn qismlarini ketma-ket qo‘shish va ularga uslublarni belgilash imkonini beradi. Bu murakkab xabarlar uchun ideal tanlovdir: loglar, chatlar, dinamik teglar bilan yangilik sarlavhalari.

Builder Spannable va Editable interfeyslarini amalga oshiradi, bu uni EditText bilan mos qiladi. Foydalanuvchi matnni tahrirlashi mumkin va uslublar saqlanadi va yangi belgilar kiritilganda to‘g‘ri siljiydi. O‘zgarmas bo‘lgan SpannableString tahrirlanadigan maydonlar uchun mos emas.

Operatsiyalar zanjiri

append() metodi builder ning o‘zini qaytaradi, bu chaqiruvlar zanjirini yaratish imkonini beradi. Matn qo‘shilgandan so‘ng, spanlar setSpan() orqali qo‘llaniladi. Pozitsiyalar builder ning joriy uzunligiga nisbatan ko‘rsatiladi. Insert() va replace() ham tarkibni aniqroq boshqarish uchun mavjud.

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

"Yangi " matni ko‘k rangda, "sharh" esa kul rangda bo‘yalgan. Ularning orasiga qo‘shimcha belgilar kiritilganda, span EXCLUSIVE bayroqlari tufayli yangi matnga ta’sir qilmaydi. Builder o‘zgartirish paytida avtomatik ravishda ichki indekslarni tuzatadi.

Spanlarning ishlashi va optimallashtirish

Ko‘p sonli spanlardan foydalanish TextView chizish samaradorligiga ta’sir qiladi. Har bir span har bir qayta chizishda updateDrawState() yoki updateMeasureState() metodini chaqiradi. O‘rta segment qurilmalarida qulay ishlash uchun bitta TextView dagi spanlar sonini 50–100 gacha cheklash tavsiya etiladi. Matn o‘lchamini o‘zgartiruvchi spanlar (RelativeSizeSpan, AbsoluteSizeSpan) har bir o‘zgarishda layout ni qayta hisoblashni talab qiladi, bu faqat rang yoki tagiga chizish uchun spanlarga qaraganda ancha qimmat.

TextAppearanceSpan

TextAppearanceSpan bitta setSpan() operatsiyasi bilan android:textAppearance xml resursidan uslublarning butun to‘plamini qo‘llash imkonini beradi. Uchta alohida span (rang, o‘lcham, shrift) o‘rniga uslubga havola bilan bitta TextAppearanceSpan ishlatiladi. Bu obyektlar sonini kamaytiradi va xizmat ko‘rsatishni soddalashtiradi — resursdagi uslubni o‘zgartirish avtomatik ravishda ushbu spandan foydalanadigan barcha matnlarga qo‘llaniladi.

Obyektlarni qayta ishlatish

Har bir setSpan() uchun yangi span namunasini yaratish chiqindi yig‘uvchiga qo‘shimcha yuk hosil qiladi. Agar spanlar takroran qo‘llanilsa, doimiy obyektlar yaratish optimaldir. Masalan, ForegroundColorSpan(Color.RED) ni companion object da saqlash va qayta ishlatish mumkin. Biroq, holatga ega spanlar (turli ishlov beruvchilar bilan ClickableSpan) har bir holat uchun alohida yaratilishi kerak.

O‘lchash va profillash

Spanlarning ishlash muammolarini diagnostika qilish uchun Android Studio dagi Layout Inspector va GPU profilidan foydalaning. Agar ko‘p sonli spanlarga ega TextView aylantirishda sezilarli darajada sekinlashsa, spanlarning bir qismini TextAppearanceSpan orqali statik uslublar bilan almashtirish yoki atributlarni maxsus UpdateAppearance ilovalarida birlashtirish orqali spanlar sonini kamaytirishni ko‘rib chiqing.

Tez-tez beriladigan savollar

SpannableString oddiy String dan qanday farq qiladi?

String — uslublarni qo‘llab-quvvatlamaydigan o‘zgarmas belgilar ketma-ketligi. SpannableString bir xil belgilarni saqlaydi, lekin qo‘shimcha ravishda formatlash haqidagi ma’lumotlarga ega Span obyektlari massivini o‘z ichiga oladi. TextView uzatilgan CharSequence turini aniqlaydi va chizish paytida spanlarni tegishli diapazonlarga qo‘llaydi. String har qanday uslub atributlarini e’tiborsiz qoldiradi va oddiy matn sifatida ko‘rsatiladi.

SpannableString dan barcha spanlarni qanday o‘chirish mumkin?

removeSpan(Object span) metodi ma’lum bir spanni o‘chiradi. To‘liq tozalash uchun getSpans(0, length, Object::class.java) ni chaqiring, u barcha spanlar massivini qaytaradi va keyin har birini removeSpan orqali o‘chiring. Muqobil ravishda, spansiz yangi SpannableString(text.toString()) yarating. SpannableStringBuilder matnni ham, spanlarni ham o‘chiradigan clear() metodiga ega.

SpannableString EditText da ishlaydimi?

SpannableString EditText da ishlaydi, lekin tahrirlanadigan matn uchun Editable ni amalga oshiradigan SpannableStringBuilder afzalroq. EditText o‘zgarishlarni kuzatish uchun Editable interfeysini talab qiladi. Agar SpannableString EditText ga uzatilsa, matn uslublar bilan ko‘rsatiladi, lekin tahrirlash paytida Android uni Editable ga aylantiradi, bu esa ba’zi spanlarni bekor qilishi mumkin.

SpannableString Compose da ishlatilishi mumkinmi?

Jetpack Compose da Android SDK spanlari to‘g‘ridan-to‘g‘ri ishlatilmaydi. Buning o‘rniga, Compose AnnotatedString ni taqdim etadi — o‘xshash imkoniyatlarga ega SpannableString ning o‘z analogi: alohida belgilar uslublari uchun SpanStyle va paragraflar uchun ParagraphStyle. SpannableString ni AnnotatedString ga aylantirish buildAnnotatedString orqali spanlar bo‘ylab iteratsiya bilan mumkin.

Maxsus Spanni qanday yaratish mumkin?

CharacterStyle dan meros oladigan sinf yarating va updateDrawState(TextPaint tp) metodini bekor qiling. Metod ichida TextPaint xususiyatlarini o‘zgartiring: rang, chiziq qalinligi, effektlar. Metrik o‘zgarishlar uchun UpdateLayout yoki MetricAffectingSpan dan foydalaning. Maxsus spanlar o‘rnatilgan spanlar kabi setSpan() orqali qo‘llaniladi.

Xulosa

  • SpannableString — Span obyektlari orqali belgilar diapazonlariga biriktirish bilan matnni uslublash uchun Android sinfi
  • CharacterStyle alohida belgilarga ta’sir qiladi, ParagraphStyle — butun paragraflarga
  • Asosiy spanlar: ForegroundColorSpan, StyleSpan, RelativeSizeSpan, URLSpan, ClickableSpan
  • SpannableStringBuilder — Editable bilan dinamik matn qurish uchun o‘zgartiriladigan versiya
  • Spanlarni birlashtirish xavfsiz — har bir span o‘z atributini mustaqil o‘zgartiradi
  • Span bayroqlari chegaralarda matn kiritishda spanning xatti-harakatini boshqaradi
  • Optimallashtirish: uslublar guruhlari uchun TextAppearanceSpan dan foydalaning va spanlar sonini 100 tagacha cheklang

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing