Kapsamlar, web’de metin stilini ayarlamak için kullanabileceğiniz güçlü işaretleme nesneleridir.
karakter veya paragraf düzeyinde
olarak ayarlayabilirsiniz. Metin nesnelerine aralık ekleyerek
metni renk ekleme, metni tıklanabilir hale getirme, metin oluşturma gibi
ve metni özelleştirilmiş bir şekilde çizme olanağı sunar. Kapsamlar
TextPaint
özelliklerini değiştirin, bir üzerine çizim yapın
Canvas
ve metin düzenini değiştirin.
Android, yaygın olarak kullanılan çeşitli metinleri kapsayan çeşitli aralık türleri sağlar oluşturabilirsiniz. Özel stil uygulamak için kendi aralıklarınızı da oluşturabilirsiniz.
Kapsam oluşturma ve uygulama
Kapsam oluşturmak için aşağıdaki tabloda listelenen sınıflardan birini kullanabilirsiniz. Sınıflar, metnin değiştirilip değiştirilmediğine, işaretlemesi değiştirilebilir ve span verilerini içeren temel veri yapısı.
Sınıf | Değişebilir metin | Değişebilir işaretleme | Veri yapısı |
---|---|---|---|
SpannedString |
Hayır | Hayır | Doğrusal dizi |
SpannableString |
Hayır | Evet | Doğrusal dizi |
SpannableStringBuilder |
Evet | Evet | Aralık ağacı |
Üç sınıfta da Spanned
kullanır. SpannableString
ve SpannableStringBuilder
,
Spannable
arayüzü.
Hangisini kullanacağınıza nasıl karar vereceğiniz aşağıda açıklanmıştır:
- Oluşturma işleminden sonra metni veya işaretlemeyi değiştirmiyorsanız
SpannedString
- Tek bir metin nesnesine az sayıda aralık eklemeniz ve
metnin kendisi salt okunur;
SpannableString
kullanın. - Oluşturma işleminden sonra metni değiştirmeniz ve
metin için
SpannableStringBuilder
kullanın. - Bir metin nesnesine çok sayıda aralık eklemeniz gerekiyorsa
salt okunur olup olmadığını kontrol etmek için
SpannableStringBuilder
kullanın.
Aralık uygulamak için setSpan(Object _what_, int _start_, int _end_, int
_flags_)
numaralı telefonu arayın
Spannable
nesnesinde oturum açın. what parametresi, kullandığınız aralığı belirtir.
metne uygulanıp start ve end parametreleri
test eder.
Bir kapsamın sınırlarına metin eklerseniz aralık otomatik olarak
eklenen metni dahil etmesi gerekir. Kapak yerine metin eklerken
sınırlar (yani start veya end dizinlerinde) flags
parametresi, aralığın eklenen metni içerecek şekilde genişletilip genişletilmeyeceğini belirler. Tekliflerinizi otomatikleştirmek ve optimize etmek için
"the"
Spannable.SPAN_EXCLUSIVE_INCLUSIVE
eklenen metni dahil etmek için flag'i kullanın ve
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
kullanabilirsiniz.
Aşağıdaki örnekte bir
ForegroundColorSpan
itibarıyla bir
dize:
Kotlin
val spannable = SpannableStringBuilder("Text is spantastic!") spannable.setSpan( ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE )
Java
SpannableStringBuilder spannable = new SpannableStringBuilder("Text is spantastic!"); spannable.setSpan( new ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE );
Aralık Spannable.SPAN_EXCLUSIVE_INCLUSIVE
kullanılarak ayarlandığı için aralık
Aşağıdaki gibi aralık sınırlarına eklenen metni içerecek şekilde genişler:
şu örneği inceleyin:
Kotlin
val spannable = SpannableStringBuilder("Text is spantastic!") spannable.setSpan( ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE ) spannable.insert(12, "(& fon)")
Java
SpannableStringBuilder spannable = new SpannableStringBuilder("Text is spantastic!"); spannable.setSpan( new ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE ); spannable.insert(12, "(& fon)");
Aynı metne birden çok aralık ekleyebilirsiniz. Aşağıdaki örnekte, kalın ve kırmızı metin oluşturmak için:
Kotlin
val spannable = SpannableString("Text is spantastic!") spannable.setSpan(ForegroundColorSpan(Color.RED), 8, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannable.setSpan( StyleSpan(Typeface.BOLD), 8, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )
Java
SpannableString spannable = new SpannableString("Text is spantastic!"); spannable.setSpan( new ForegroundColorSpan(Color.RED), 8, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); spannable.setSpan( new StyleSpan(Typeface.BOLD), 8, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
Android aralık türleri
Android, API'de 20'den fazla aralık türü sunar. android.text.style paketinden ekleyin. Android, aralıkları iki temel şekilde kategorilere ayırır:
- Yayılma, metni nasıl etkiler? Kapsama alanı, metnin görünümünü veya metni etkileyebilir kullanabilirsiniz.
- Genişleme kapsamı: Bazı aralıklar tek tek karakterlere uygulanabilir, bazıları ise tek tek karakterlere uygulanabilir tüm paragrafa uygulanmalıdır.
Aşağıdaki bölümlerde bu kategoriler daha ayrıntılı olarak açıklanmaktadır.
Metin görünümünü etkileyen aralıklar
Karakter düzeyinde uygulanan bazı kapsamlar, metin görünümünü etkiler: Örneğin,
Metnin veya arka plan renginin değiştirilmesi, alt çizgi veya üstü çizili ekleme. Bu
kapsamı
CharacterStyle
sınıfı.
Aşağıdaki kod örneğinde, alt çizgiye UnderlineSpan
nasıl uygulanacağı gösterilmektedir
metin:
Kotlin
val string = SpannableString("Text with underline span") string.setSpan(UnderlineSpan(), 10, 19, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
Java
SpannableString string = new SpannableString("Text with underline span"); string.setSpan(new UnderlineSpan(), 10, 19, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Yalnızca metin görünümünü etkileyen aralıklar, metnin herhangi bir öğe olmadan yeniden çizilmesini
düzenin yeniden hesaplanmasını tetikler. Bu aralıklar
UpdateAppearance
ve uzat
CharacterStyle
.
CharacterStyle
alt sınıf,
TextPaint
.
Metin metriklerini etkileyen aralıklar
Karakter düzeyinde uygulanan diğer aralıklar, satır gibi metin metriklerini etkiler
ve metin boyutunu seçin. Bu aralıklar
MetricAffectingSpan
sınıfını kullanır.
Aşağıdaki kod örneği,
RelativeSizeSpan
metin boyutunu %50 büyütür:
Kotlin
val string = SpannableString("Text with relative size span") string.setSpan(RelativeSizeSpan(1.5f), 10, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
Java
SpannableString string = new SpannableString("Text with relative size span"); string.setSpan(new RelativeSizeSpan(1.5f), 10, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Metin metriklerini etkileyen bir aralık uygulandığında, gözlemlenen nesne Doğru düzen ve oluşturma için metni yeniden ölçün. Örneğin, metin boyutu kelimelerin farklı satırlarda görünmesine neden olabilir. Önceki uygulama spanlama, metin düzeninin yeniden hesaplanmasını ve yeniden çizilmesini tetiklemesini metin.
Metin metriklerini etkileyen aralıklar MetricAffectingSpan
sınıfını genişletir.
alt sınıfların, aralığın metin ölçümünü nasıl etkilediğini tanımlamasına olanak tanıyan soyut sınıf
(TextPaint
) erişimi sağlayarak. MetricAffectingSpan
uzantısından itibaren
CharacterSpan
, alt sınıflar karakterdeki metnin görünümünü etkiler
seviyesinde olmalıdır.
Paragrafları etkileyen aralıklar
Yayılma, paragraf düzeyindeki metni de etkileyebilir, örneğin
veya kenar boşluğunu kullanabilirsiniz. Tüm paragrafları etkileyen aralıklar
ParagraphStyle
uygulayın. Alıcı:
kapsamları kullanırsanız, bu aralıkların bitişi hariç paragrafın tamamına eklersiniz
yeni satır karakteri ekleyin. Bir paragraf kapsamını
Android, aralığı hiç uygulamaz.
Şekil 8'de Android'in metindeki paragrafları nasıl ayırdığı gösterilmektedir.
Aşağıdaki kod örneği,
QuoteSpan
öğesini bir paragrafa ekleyebilirsiniz. Lütfen
aralığı bir reklamın başlangıcı veya bitişi dışında herhangi bir konuma
paragrafı nedeniyle Android, stili hiç uygulamaz.
Kotlin
spannable.setSpan(QuoteSpan(color), 8, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Java
spannable.setSpan(new QuoteSpan(color), 8, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Özel aralıklar oluşturma
Mevcut Android sürümünde sağlanandan daha fazla işleve ihtiyacınız varsa özel bir aralık uygulayabilirsiniz. Kendi aralığınızı uygularken aralığınızın metni karakter düzeyinde mi yoksa paragraf düzeyinde mi etkilediği metnin düzenini veya görünümünü de etkileyip etkilemediğini belirler. Bu, kullanıcıların genişletebileceğiniz temel sınıfları ve ihtiyaç duyabileceğiniz arayüzleri belirleme pek çok yolu vardır. Referans için aşağıdaki tabloyu kullanın:
Senaryo | Sınıf veya arayüz |
---|---|
Aralığınız, metni karakter düzeyinde etkiler. | CharacterStyle |
Aralığınız metin görünümünü etkiler. | UpdateAppearance |
Aralığınız metin metriklerini etkiler. | UpdateLayout |
Aralığınız, paragraf düzeyindeki metni etkiler. | ParagraphStyle |
Örneğin, metin boyutunu ve değerini değiştiren özel bir kapsam uygulamanız
renk, RelativeSizeSpan
öğesini uzat. Devralma yoluyla, RelativeSizeSpan
CharacterStyle
öğesini genişletir ve iki Update
arayüzünü uygular. Bu tarihten itibaren
sınıfı zaten updateDrawState
ve updateMeasureState
için geri çağırmalar sağlıyor.
özel davranışınızı uygulamak için bu geri çağırmaları geçersiz kılabilirsiniz. İlgili içeriği oluşturmak için kullanılan
aşağıdaki kod, RelativeSizeSpan
ve
TextPaint
renginin rengini ayarlamak için updateDrawState
geri çağırmasını geçersiz kılar:
Kotlin
class RelativeSizeColorSpan( size: Float, @ColorInt private val color: Int ) : RelativeSizeSpan(size) { override fun updateDrawState(textPaint: TextPaint) { super.updateDrawState(textPaint) textPaint.color = color } }
Java
public class RelativeSizeColorSpan extends RelativeSizeSpan { private int color; public RelativeSizeColorSpan(float spanSize, int spanColor) { super(spanSize); color = spanColor; } @Override public void updateDrawState(TextPaint textPaint) { super.updateDrawState(textPaint); textPaint.setColor(color); } }
Bu örnekte, özel aralığın nasıl oluşturulacağı gösterilmektedir. Tekliflerinizi otomatik olarak
metne RelativeSizeSpan
ve ForegroundColorSpan
uygulayarak etki yaratırsınız.
Aralık kullanımını test et
Spanned
arayüzü, hem aralıkları ayarlamanıza hem de
metin. Test sırasında bir Android JUnit uygulayın
Doğru aralıkların eklendiğini doğrulamak için test'i kullanın
doğru konumda. Metin Stili örneği
uygulama
Metne BulletPointSpan
ekleyin. Aşağıdaki kod örneğinde, Google Yapay Zeka'nın
madde işaretlerinin beklendiği gibi görünüp görünmediğini belirtin:
Kotlin
@Test fun textWithBulletPoints() { val result = builder.markdownToSpans("Points\n* one\n+ two") // Check whether the markup tags are removed. assertEquals("Points\none\ntwo", result.toString()) // Get all the spans attached to the SpannedString. val spans = result.getSpans<Any>(0, result.length, Any::class.java) // Check whether the correct number of spans are created. assertEquals(2, spans.size.toLong()) // Check whether the spans are instances of BulletPointSpan. val bulletSpan1 = spans[0] as BulletPointSpan val bulletSpan2 = spans[1] as BulletPointSpan // Check whether the start and end indices are the expected ones. assertEquals(7, result.getSpanStart(bulletSpan1).toLong()) assertEquals(11, result.getSpanEnd(bulletSpan1).toLong()) assertEquals(11, result.getSpanStart(bulletSpan2).toLong()) assertEquals(14, result.getSpanEnd(bulletSpan2).toLong()) }
Java
@Test public void textWithBulletPoints() { SpannedString result = builder.markdownToSpans("Points\n* one\n+ two"); // Check whether the markup tags are removed. assertEquals("Points\none\ntwo", result.toString()); // Get all the spans attached to the SpannedString. Object[] spans = result.getSpans(0, result.length(), Object.class); // Check whether the correct number of spans are created. assertEquals(2, spans.length); // Check whether the spans are instances of BulletPointSpan. BulletPointSpan bulletSpan1 = (BulletPointSpan) spans[0]; BulletPointSpan bulletSpan2 = (BulletPointSpan) spans[1]; // Check whether the start and end indices are the expected ones. assertEquals(7, result.getSpanStart(bulletSpan1)); assertEquals(11, result.getSpanEnd(bulletSpan1)); assertEquals(11, result.getSpanStart(bulletSpan2)); assertEquals(14, result.getSpanEnd(bulletSpan2)); }
Daha fazla test örneği için bkz. GitHub'da MarkdownBuilderTest
Özel aralıkları test etme
Test aralıkları sırasında TextPaint
öğesinin beklenen içeriği içerdiğini doğrulayın
ve Canvas
üzerinde doğru öğelerin görünmesini sağlayın. Örneğin,
Örneğin,
biraz metin. Madde işaretinde belirtilen boyut ve renk var ve boşluk var
madde işareti arasına girin.
Bir AndroidJUnit testi uygulayarak bu sınıfın davranışını test edebilirsiniz. şunları kontrol ediyor:
- Kapsamı doğru uygularsanız, belirtilen boyutta bir madde işareti ve tuvalde renk görünüyor ve sol ile arasında uygun boşluk var girin.
- Kapsamı uygulamazsanız özel davranışların hiçbiri görünmez.
Bu testlerin uygulanma şeklini TextStyling sample'ı tıklayın.
Tuvalle ilgili bir model oluşturup modellenmiş öğeyi ileterek Canvas etkileşimlerini test edebilirsiniz.
nesne
drawLeadingMargin()
yöntemini kullanarak ve doğru yöntemlerin doğru yöntemle çağrıldığını
parametreleridir.
Daha fazla span test örneğini şurada bulabilirsiniz: BulletPointSpanTest.
Aralıkları kullanmayla ilgili en iyi uygulamalar
TextView
cihazındaki metni ayarlamanın bellek açısından verimli birkaç yolu vardır.
görünür.
Temel metni değiştirmeden bir yayılma metni ekleme veya çıkarma
TextView.setText()
içeren öğeler, spanları farklı şekilde işleyen birden çok aşırı yükleme içerir. Örneğin, şunları yapabilirsiniz:
aşağıdaki kodla bir Spannable
metin nesnesi ayarlayın:
Kotlin
textView.setText(spannableObject)
Java
textView.setText(spannableObject);
Bu aşırı setText()
yüklemesi çağrılırken TextView
,
Spannable
, SpannedString
olarak hatırlanır ve CharSequence
olarak bellekte tutulur.
Bu, metninizin ve aralıkların sabit olduğu anlamına gelir. Dolayısıyla,
metni veya kapsamları güncelleyin, yeni bir Spannable
nesnesi oluşturun ve çağrıyı
setText()
, bu da aynı zamanda elektriğin yeniden ölçülmesini ve
kullanır.
Aralıkların değiştirilebilir olması gerektiğini belirtmek için bunun yerine şunu kullanabilirsiniz:
setText(CharSequence text, TextView.BufferType
type)
aşağıdaki örnekte gösterildiği gibi:
Kotlin
textView.setText(spannable, BufferType.SPANNABLE) val spannableText = textView.text as Spannable spannableText.setSpan( ForegroundColorSpan(color), 8, spannableText.length, SPAN_INCLUSIVE_INCLUSIVE )
Java
textView.setText(spannable, BufferType.SPANNABLE); Spannable spannableText = (Spannable) textView.getText(); spannableText.setSpan( new ForegroundColorSpan(color), 8, spannableText.getLength(), SPAN_INCLUSIVE_INCLUSIVE);
Bu örnekte
BufferType.SPANNABLE
parametresi, TextView
öğesinin bir SpannableString
oluşturmasına neden olur ve
TextView
tarafından tutulan CharSequence
nesnesi artık değişebilir işaretlemeye sahip ve
sabit metindir. Kapsamı güncellemek için metni Spannable
olarak alın ve ardından
aralıkları gerektiği gibi güncelleyin.
Aralıkları eklediğinizde, ayırdığınızda veya yeniden konumlandırdığınızda TextView
otomatik olarak
yansıtması için e-posta alır. Dahili bir özelliği değiştirirseniz
mevcut bir kapsamın adı, görünümle ilgili değişiklikler yapmak için invalidate()
veya
Metrikle ilgili değişiklikler yapmak için requestLayout()
.
TextView'da metni birden çok kez ayarlama
Bazı durumlarda, örneğin
RecyclerView.ViewHolder
bir TextView
metnini yeniden kullanmak ve metni birden çok kez ayarlamak isteyebilirsiniz. Ölçüt
varsayılan olarak, BufferType
değerini ayarlayıp ayarlamamanızdan bağımsız olarak, TextView
CharSequence
nesnesinin bir kopyasını oluşturur ve bunu bellekte tutar. Bu da tüm
TextView
güncelleme bilinçli olarak yapıldı. Orijinali güncelleyemezsiniz
Metni güncellemek için CharSequence
nesnesi. Bu, her yeni ayar yaptığınızda
metnini ayarlarsanız TextView
yeni bir nesne oluşturur.
Bu işlem üzerinde daha fazla kontrol sahibi olmak ve ekstra nesneden kaçınmak isterseniz
kendi oluşturduğunuz içerikleri
Spannable.Factory
ve geçersiz kılma
newSpannable()
.
Yeni bir metin nesnesi oluşturmak yerine mevcut metin nesnesini yayınlayabilir ve döndürebilirsiniz
Aşağıdaki örnekte gösterildiği gibi, Spannable
olarak CharSequence
:
Kotlin
val spannableFactory = object : Spannable.Factory() { override fun newSpannable(source: CharSequence?): Spannable { return source as Spannable } }
Java
Spannable.Factory spannableFactory = new Spannable.Factory(){ @Override public Spannable newSpannable(CharSequence source) { return (Spannable) source; } };
Aşağıdaki durumlarda textView.setText(spannableObject, BufferType.SPANNABLE)
kullanmanız gerekir:
metni de belirleyebilirsiniz. Aksi takdirde, CharSequence
kaynağı Spanned
olarak oluşturulur
örneğe dönüştürülemiyor ve Spannable
öğesine dönüştürülemiyor. Bu da newSpannable()
için
ClassCastException
.
newSpannable()
öğesini geçersiz kıldıktan sonra TextView
adlı kullanıcıdan yeni Factory
öğesini kullanmasını isteyin:
Kotlin
textView.setSpannableFactory(spannableFactory)
Java
textView.setSpannableFactory(spannableFactory);
Spannable.Factory
nesnesini bir kez, referans aldıktan hemen sonra ayarlayın
TextView
. RecyclerView
kullanıyorsanızFactory
önce görüntüleme sayınızı artırmanız gerekir. Böylece,
RecyclerView
, yeni bir öğeyi ViewHolder
cihazınıza bağlar.
Dahili span özelliklerini değiştirme
Değişebilir bir aralığın yalnızca dahili bir özelliğini (ör.
özel bir madde işareti aralığında madde işareti rengi kullanarak
Oluşturulan aralığın referansını koruyarak birden çok kez setText()
.
Kapsamı değiştirmeniz gerektiğinde referansı değiştirebilir ve ardından
Türüne bağlı olarak TextView
üzerinde invalidate()
veya requestLayout()
yeni bir özellik ekleyin.
Aşağıdaki kod örneğinde, özel bir madde işareti uygulaması bir düğmeye dokunulduğunda gri olan varsayılan kırmızı rengi:
Kotlin
class MainActivity : AppCompatActivity() { // Keeping the span as a field. val bulletSpan = BulletPointSpan(color = Color.RED) override fun onCreate(savedInstanceState: Bundle?) { ... val spannable = SpannableString("Text is spantastic") // Setting the span to the bulletSpan field. spannable.setSpan( bulletSpan, 0, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE ) styledText.setText(spannable) button.setOnClickListener { // Change the color of the mutable span. bulletSpan.color = Color.GRAY // Color doesn't change until invalidate is called. styledText.invalidate() } } }
Java
public class MainActivity extends AppCompatActivity { private BulletPointSpan bulletSpan = new BulletPointSpan(Color.RED); @Override protected void onCreate(Bundle savedInstanceState) { ... SpannableString spannable = new SpannableString("Text is spantastic"); // Setting the span to the bulletSpan field. spannable.setSpan(bulletSpan, 0, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE); styledText.setText(spannable); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Change the color of the mutable span. bulletSpan.setColor(Color.GRAY); // Color doesn't change until invalidate is called. styledText.invalidate(); } }); } }
Android KTX uzantı işlevlerini kullanma
Android KTX, aralıklarla çalışmayı sağlayan uzantı işlevleri de içerir. daha kolay olur. Daha fazla bilgi edinmek için androidx.core.text paketinden yararlanın.