स्पैन

लिखने का तरीका आज़माएं
Android के लिए, Jetpack Compose हमारा सुझाया गया यूज़र इंटरफ़ेस (यूआई) टूलकिट है. Compose में टेक्स्ट इस्तेमाल करने का तरीका जानें.

स्पैन शक्तिशाली मार्कअप ऑब्जेक्ट हैं जिनका उपयोग आप वर्ण या पैराग्राफ़ लेवल. टेक्स्ट ऑब्जेक्ट में स्पैन अटैच करके, जिसमें अलग-अलग तरह के टेक्स्ट शामिल हैं. जैसे, रंग जोड़ना, टेक्स्ट को क्लिक करने लायक बनाना, टेक्स्ट के साइज़ को स्केल करने और पसंद के हिसाब से टेक्स्ट बनाने की सुविधा मिलती है. स्पैन ये भी कर सकते हैं TextPaint प्रॉपर्टी बदलें, Canvas, और टेक्स्ट का लेआउट बदलें.

Android कई तरह के स्पैन उपलब्ध कराता है, जिनमें कई तरह के सामान्य टेक्स्ट शामिल होते हैं स्टाइल के पैटर्न को समझ सकते हैं. पसंद के मुताबिक स्टाइल लागू करने के लिए, खुद भी स्पैन बनाए जा सकते हैं.

स्पैन बनाना और लागू करना

स्पैन बनाने के लिए, नीचे दी गई टेबल में दी गई क्लास में से किसी एक का इस्तेमाल किया जा सकता है. क्लास इस आधार पर अलग-अलग होती हैं कि टेक्स्ट में बदलाव किया जा सकता है या नहीं, मार्कअप में बदलाव किया जा सकता है और यह कि किस बुनियादी डेटा स्ट्रक्चर में स्पैन डेटा है.

कक्षा बदला जा सकने वाला टेक्स्ट बदलाव किए जा सकने वाले मार्कअप डेटा स्ट्रक्चर
SpannedString नहीं नहीं लीनियर अरे
SpannableString नहीं हां लीनियर अरे
SpannableStringBuilder हां हां इंटरवल ट्री

तीनों क्लास, Spanned की अवधि को बढ़ाती हैं इंटरफ़ेस पर कॉपी करने की सुविधा मिलती है. SpannableString और SpannableStringBuilder भी Spannable इंटरफ़ेस.

यहां दिए गए तरीके से तय करें कि किसका इस्तेमाल करना है:

  • अगर कॉन्टेंट बनाने के बाद, टेक्स्ट या मार्कअप में बदलाव नहीं किया जा रहा है, तो SpannedString.
  • अगर आपको किसी एक टेक्स्ट ऑब्जेक्ट में कुछ स्पैन अटैच करने हों और टेक्स्ट को सिर्फ़ पढ़ा जा सकता है, इसलिए SpannableString का इस्तेमाल करें.
  • अगर टेक्स्ट बनाने के बाद उसमें बदलाव करना है, तो स्पैन अटैच करें टेक्स्ट के लिए, SpannableStringBuilder का इस्तेमाल करें.
  • अगर आपको किसी टेक्स्ट ऑब्जेक्ट में कई स्पैन अटैच करने हैं, भले ही अगर टेक्स्ट रीड-ओनली है, तो SpannableStringBuilder का इस्तेमाल करें.

स्पैन लागू करने के लिए, setSpan(Object _what_, int _start_, int _end_, int _flags_) पर कॉल करें Spannable ऑब्जेक्ट पर. what पैरामीटर से पता चलता है कि आप किस अवधि में हैं टेक्स्ट पर लागू कर सकते हैं और start और end पैरामीटर से उस टेक्स्ट पर स्पैन करें, जिस पर आप स्पैन लागू कर रहे हैं.

किसी स्पैन की सीमाओं के अंदर टेक्स्ट डालने पर, स्पैन अपने-आप इतना बड़ा हो जाता है डाला गया टेक्स्ट शामिल करें. स्पैन पर टेक्स्ट डालते समय सीमाएं—यानी, शुरू या खत्म इंडेक्स पर—फ़्लैग पैरामीटर से तय होता है कि शामिल किए गए टेक्स्ट को शामिल करने के लिए स्पैन बढ़ता है या नहीं. इस्तेमाल की जाने वाली चीज़ें यह Spannable.SPAN_EXCLUSIVE_INCLUSIVE डाले गए टेक्स्ट को शामिल करने के लिए फ़्लैग करें, और Spannable.SPAN_EXCLUSIVE_EXCLUSIVE डाले गए टेक्स्ट को बाहर रखने के लिए.

नीचे दिए गए उदाहरण में, ForegroundColorSpan से स्ट्रिंग:

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
);
इस इमेज में स्लेटी रंग का टेक्स्ट और आंशिक रूप से लाल रंग का टेक्स्ट दिख रहा है.
पहली इमेज. टेक्स्ट को इससे स्टाइल किया गया ForegroundColorSpan.

स्पैन को Spannable.SPAN_EXCLUSIVE_INCLUSIVE का इस्तेमाल करके सेट किया गया है, इसलिए स्पैन यह स्पैन सीमाओं में सम्मिलित किए गए टेक्स्ट को शामिल करने के लिए बड़ा हो जाता है, जैसा कि नीचे दिया गया उदाहरण:

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)");
इस इमेज में दिखाया गया है कि SPAN_EXCLUSIVE_INCLUSIVE का इस्तेमाल करने पर, स्पैन में ज़्यादा टेक्स्ट कैसे शामिल किया जाता है.
दूसरी इमेज. शामिल करने के लिए फैलाव का विस्तार होता है अतिरिक्त टेक्स्ट जोड़ें Spannable.SPAN_EXCLUSIVE_INCLUSIVE.

एक ही टेक्स्ट में कई स्पैन अटैच किए जा सकते हैं. नीचे दिए गए उदाहरण में बताया गया है कि बोल्ड और लाल टेक्स्ट बनाने के लिए:

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
);
इमेज में एक से ज़्यादा स्पैन वाला टेक्स्ट दिख रहा है: `ForegroundColorSpan(Color.RED)` और `StyleSpan(BOLD)`
तीसरी इमेज. एक से ज़्यादा स्पैन वाला टेक्स्ट: ForegroundColorSpan(Color.RED) और StyleSpan(BOLD).

Android स्पैन प्रकार

Android android.text.style पैकेज में दिया गया तरीका अपनाएं. Android, स्पैन को दो मुख्य तरीकों से कैटगरी में बांटता है:

  • स्पैन, टेक्स्ट पर कैसे असर डालता है: स्पैन का असर, टेक्स्ट के दिखने के तरीके या टेक्स्ट पर पड़ सकता है मेट्रिक.
  • स्पैन स्कोप: कुछ स्पैन अलग-अलग वर्णों पर लागू किए जा सकते हैं, जबकि कुछ अन्य पर लागू किए जा सकते हैं पूरे पैराग्राफ़ पर लागू किया जाना चाहिए.
अवधि की अलग-अलग कैटगरी दिखाने वाली इमेज
चौथी इमेज. Android स्पैन की कैटगरी.

इन सेक्शन में, इन कैटगरी के बारे में ज़्यादा जानकारी दी गई है.

टेक्स्ट के दिखने के तरीके पर असर डालने वाले स्पैन

वर्ण के लेवल पर लागू होने वाले कुछ स्पैन, टेक्स्ट के दिखने के तरीके पर असर डालते हैं, जैसे कि टेक्स्ट या बैकग्राउंड का रंग बदलना और अंडरलाइन या स्ट्राइकथ्रू जोड़ना. ये स्पैन, CharacterStyle क्लास.

यहां दिए गए कोड के उदाहरण में, अंडरलाइन करने के लिए UnderlineSpan को लागू करने का तरीका बताया गया है लेख:

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);
`अंडरलाइनस्पैन` का इस्तेमाल करके, टेक्स्ट को अंडरलाइन करने का तरीका दिखाने वाली इमेज
पांचवीं इमेज. टेक्स्ट को अंडरलाइन करने के लिए UnderlineSpan.

सिर्फ़ टेक्स्ट के दिखने के तरीके पर असर डालने वाले स्पैन, बिना टेक्स्ट वाले फिर से दोहराए जाने की सुविधा को ट्रिगर करते हैं इससे लेआउट को दोबारा कैलकुलेट किया जा सकता है. ये अवधियां लागू की जाती हैं UpdateAppearance और समयसीमा बढ़ाएं CharacterStyle. CharacterStyle सब-क्लास यह तय करती हैं कि ऐक्सेस देकर, टेक्स्ट कैसे बनाया जाए TextPaint को अपडेट करें.

टेक्स्ट मेट्रिक पर असर डालने वाले स्पैन

वर्ण के लेवल पर लागू होने वाले अन्य स्पैन, टेक्स्ट मेट्रिक पर असर डालते हैं, जैसे कि लाइन ऊंचाई और टेक्स्ट का साइज़. ये विस्तार MetricAffectingSpan क्लास.

नीचे दिए गए उदाहरण से RelativeSizeSpan कि टेक्स्ट का साइज़ 50% बढ़ाता है:

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);
RelativeSizeSpan का इस्तेमाल दिखाने वाली इमेज
छठी इमेज. टेक्स्ट को बड़ा करने के लिए, RelativeSizeSpan.

टेक्स्ट मेट्रिक पर असर डालने वाले स्पैन का इस्तेमाल करने से, ऑब्ज़र्व करने वाला ऑब्जेक्ट सही लेआउट और रेंडरिंग के लिए टेक्स्ट का फिर से आकलन करें—उदाहरण के लिए, टेक्स्ट के साइज़ की वजह से शब्द अलग-अलग लाइनों में दिख सकते हैं. पिछले कीवर्ड को लागू करना span की मदद से टेक्स्ट लेआउट को रीमेज़र, दोबारा कैलकुलेट किया जाता है, और फिर से लेख.

टेक्स्ट मेट्रिक पर असर डालने वाले स्पैन, MetricAffectingSpan क्लास को बढ़ाते हैं, ऐब्सट्रैक्ट क्लास, जिसकी मदद से सब-क्लास यह तय कर सकती हैं कि स्पैन, टेक्स्ट मेज़रमेंट पर कैसे असर डालता है TextPaint का ऐक्सेस देकर. MetricAffectingSpan की अवधि बढ़ा दी गई है CharacterSpan, सब-क्लास, वर्ण पर टेक्स्ट के दिखने पर असर डालती हैं लेवल.

पैराग्राफ़ पर असर डालने वाले स्पैन

स्पैन, पैराग्राफ़ लेवल पर मौजूद टेक्स्ट पर भी असर डाल सकता है, जैसे कि टेक्स्ट के एक ब्लॉक के अलाइनमेंट या मार्जिन को. पूरे पैराग्राफ़ पर असर डालने वाले स्पैन ParagraphStyle लागू करें. यहां की यात्रा पर हूं इन स्पैन का इस्तेमाल करें, तो आपको इन्हें पूरे पैराग्राफ़ में अटैच करना होगा. हालांकि, आखिर में लाइन में मौजूद नया वर्ण. अगर आपको पैराग्राफ़ स्पैन के बजाय, किसी और चीज़ में पैराग्राफ़ स्पैन लागू करना हो पूरे पैराग्राफ़ में करते हैं, तो Android स्पैन को बिलकुल भी लागू नहीं करता.

इमेज 8 में दिखाया गया है कि Android, टेक्स्ट में पैराग्राफ़ को कैसे अलग करता है.

सातवीं इमेज. Android में, पैराग्राफ़ के आखिर में नई लाइन (\n) वर्ण.

कोड का यह उदाहरण, QuoteSpan लेकर, पैराग्राफ़ के लिए साइज़ तय करें. ध्यान दें कि अगर आप स्पैन को, आगे या पीछे के हिस्से के अलावा किसी भी दूसरी पोज़िशन पर अटैच करते हैं पैराग्राफ़ में, Android शैली को बिलकुल भी लागू नहीं करता है.

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);
कोटSpan का उदाहरण दिखाने वाली इमेज
आठवीं इमेज. QuoteSpan पैराग्राफ़ पर लागू की जाती है.

कस्टम स्पैन बनाएं

अगर आपको मौजूदा Android में दी गई सुविधा से ज़्यादा सुविधाएं चाहिए स्पैन, तो आप एक कस्टम स्पैन लागू कर सकते हैं. अपने स्पैन को लागू करते समय, तय करें आपके स्पैन का असर वर्ण लेवल पर टेक्स्ट पर पड़ता है या पैराग्राफ़ लेवल पर और साथ ही, इससे टेक्स्ट के लेआउट या लुक पर असर पड़ता है. इससे आपको और यह तय किया जा सकता है कि किन बेस क्लास को बढ़ाया जा सकता है और आपको किन इंटरफ़ेस की ज़रूरत पड़ सकती है . रेफ़रंस के लिए, यहां दी गई टेबल का इस्तेमाल करें:

स्थिति क्लास या इंटरफ़ेस
आपके स्पैन का असर, वर्ण लेवल पर टेक्स्ट पर पड़ता है. CharacterStyle
आपके स्पैन का असर, टेक्स्ट के दिखने के तरीके पर पड़ता है. UpdateAppearance
आपके स्पैन का असर टेक्स्ट मेट्रिक पर पड़ता है. UpdateLayout
आपके स्पैन का असर, पैराग्राफ़ लेवल पर टेक्स्ट पर पड़ता है. ParagraphStyle

उदाहरण के लिए, अगर आपको टेक्स्ट का साइज़ और रंग, RelativeSizeSpan तक बढ़ाएं. इनहेरिटेंस के ज़रिए, RelativeSizeSpan यह CharacterStyle तक बड़ा करता है और दो Update इंटरफ़ेस लागू करता है. इस तारीख से क्लास पहले से ही updateDrawState और updateMeasureState के लिए कॉलबैक की सुविधा देती है, अपनी पसंद के हिसाब से व्यवहार लागू करने के लिए, इन कॉलबैक को बदला जा सकता है. कॉन्टेंट बनाने यह कोड एक कस्टम स्पैन बनाता है, जो RelativeSizeSpan को बढ़ाता है और TextPaint का रंग सेट करने के लिए, updateDrawState कॉलबैक को ओवरराइड करता है:

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);
    }
}

इस उदाहरण में कस्टम स्पैन बनाने का तरीका बताया गया है. लक्ष्य हासिल करने के लिए, टेक्स्ट पर RelativeSizeSpan और ForegroundColorSpan लागू करके इफ़ेक्ट डालें.

अवधि के इस्तेमाल की जांच करें

Spanned इंटरफ़ेस की मदद से, स्पैन सेट करने के साथ-साथ स्पैन वापस पाने की सुविधा भी मिलती है टेक्स्ट. जांच करते समय, किसी Android JUnit को लागू करें परीक्षण की जांच करें कि सही स्पैन जोड़े गए हैं सही जगहों पर. टेक्स्ट स्टाइलिंग का सैंपल ऐप्लिकेशन इसमें ऐसा स्पैन है जो अटैच करके बुलेट पॉइंट पर मार्कअप लागू करता है टेक्स्ट के लिए BulletPointSpan. नीचे दिए गए उदाहरण में, जांच करने का तरीका बताया गया है क्या बुलेट पॉइंट उम्मीद के मुताबिक दिख रहे हैं:

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));
}

जांच के और उदाहरणों के लिए, देखें GitHub पर MarkdownBuilderTest.

कस्टम स्पैन की जांच करें

स्पैन की जांच करते समय, पुष्टि करें कि TextPaint में उम्मीद के मुताबिक डेटा शामिल है बदलाव करें और यह कि सही एलिमेंट आपके Canvas पर दिखें. इसके लिए उदाहरण के लिए, एक कस्टम स्पैन लागू करने पर विचार करें, जो कुछ टेक्स्ट. बुलेट पॉइंट के लिए एक खास साइज़ और रंग दिया गया हो, लेकिन उसमें खाली जगह हो बनाए जाने योग्य क्षेत्र के बाएं मार्जिन और बुलेट पॉइंट के बीच में होना चाहिए.

AndroidJUnit की जांच लागू करके, इस क्लास के व्यवहार की जांच की जा सकती है. इनकी जांच करें:

  • अगर आपने स्पैन सही तरीके से लागू किया है, तो तय किए गए साइज़ का बुलेट पॉइंट और कैनवस पर रंग दिखता है और बाईं तरफ़ सही स्पेस मौजूद है मार्जिन और बुलेट पॉइंट.
  • स्पैन लागू नहीं करने पर, पसंद के मुताबिक बनाया गया कोई भी व्यवहार नहीं दिखता है.

TextStyling में इन टेस्ट को लागू करने का तरीका देखा जा सकता है GitHub पर सैंपल दिया गया है.

कैनवस के इंटरैक्शन की जांच की जा सकती है. इसके लिए, कैनवस को मज़ाक़िया तरीके से पास करें पर आपत्ति drawLeadingMargin() तरीका होता है. साथ ही, इस बात की पुष्टि की जाती है कि सही तरीकों को सही पैरामीटर का इस्तेमाल करें.

आपको यहां स्पैन टेस्ट के ज़्यादा सैंपल मिल सकते हैं BulletPointSpanTest.

स्पैन इस्तेमाल करने के सबसे सही तरीके

TextView में टेक्स्ट सेट करने के लिए, मेमोरी की कम से कम खपत वाले कई तरीके उपलब्ध हैं. आपकी ज़रूरतों के हिसाब से.

दिए गए टेक्स्ट को बदले बिना, स्पैन को अटैच करें या अलग करें

TextView.setText() में एक से ज़्यादा ओवरलोड होते हैं, जो स्पैन को अलग-अलग तरीके से हैंडल करते हैं. उदाहरण के लिए, आपके पास इस कोड के साथ Spannable टेक्स्ट ऑब्जेक्ट सेट करें:

Kotlin

textView.setText(spannableObject)

Java

textView.setText(spannableObject);

setText() के इस ओवरलोड को कॉल करने पर, TextView आपके Spannable को SpannedString के तौर पर सेव किया है और इसे CharSequence के तौर पर मेमोरी में रखा है. इसका मतलब है कि आपके टेक्स्ट और स्पैन में कोई बदलाव नहीं किया जा सकता. इसलिए, ज़रूरी होने पर टेक्स्ट या स्पैन अपडेट करें, नया Spannable ऑब्जेक्ट बनाएं और कॉल करें setText() को दोबारा अपलोड किया, जिससे क्लिप को मापने के साथ-साथ, लेआउट.

यह बताने के लिए कि स्पैन में बदलाव किया जा सकता है, setText(CharSequence text, TextView.BufferType type) जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:

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

इस उदाहरण में, BufferType.SPANNABLE पैरामीटर की वजह से TextView, SpannableString बना देता है और TextView में सेव किए गए CharSequence ऑब्जेक्ट में अब बदलाव किए जा सकने वाले मार्कअप हैं और ऐसा टेक्स्ट जिसमें बदलाव नहीं किया जा सकता. स्पैन को अपडेट करने के लिए, टेक्स्ट को Spannable के तौर पर फिर से पाएं. इसके बाद स्पैन को ज़रूरत के मुताबिक अपडेट करें.

स्पैन को अटैच करने, अलग करने या उनकी जगह बदलने पर, TextView अपने-आप जुड़ जाता है अपडेट करता है. अगर आप किसी अंदरूनी एट्रिब्यूट में बदलाव करते हैं को खोलने के लिए, invalidate() को कॉल करें मेट्रिक से जुड़े बदलाव करने के लिए requestLayout().

टेक्स्ट व्यू में टेक्स्ट को कई बार सेट करना

कुछ मामलों में, जैसे RecyclerView.ViewHolder हो सकता है कि आप TextView का फिर से इस्तेमाल करना और टेक्स्ट को कई बार सेट करना चाहें. इन्होंने बदलाव किया है डिफ़ॉल्ट रूप से, BufferType को सेट किए जाने की परवाह किए बिना, TextView यह CharSequence ऑब्जेक्ट की एक कॉपी होती है और उसे मेमोरी में रखती है. इससे सभी TextView जान-बूझकर अपडेट किए जाते हैं—आप मूल कॉपी को अपडेट नहीं कर सकते टेक्स्ट अपडेट करने के लिए CharSequence ऑब्जेक्ट. इसका मतलब है कि हर बार नया टेक्स्ट के तौर पर, TextView एक नया ऑब्जेक्ट बनाता है.

अगर आपको इस प्रोसेस पर ज़्यादा कंट्रोल चाहिए और अतिरिक्त ऑब्जेक्ट से बचना है, तो क्रिएशन के लिए, खुद का टूल इस्तेमाल किया जा सकता है. Spannable.Factory और बदलाव newSpannable(). नया टेक्स्ट ऑब्जेक्ट बनाने के बजाय, मौजूदा ऑब्जेक्ट को कास्ट करके, उसे लौटाया जा सकता है Spannable के तौर पर 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;
    }
};

आपको textView.setText(spannableObject, BufferType.SPANNABLE) का इस्तेमाल तब करना होगा, जब टेक्स्ट सेट करना. ऐसा न करने पर, सोर्स CharSequence को Spanned के तौर पर बनाया जाता है जिसे Spannable पर कास्ट नहीं किया जा सकता, जिसकी वजह से newSpannable() ClassCastException.

newSpannable() बदलने के बाद, TextView को नया Factory इस्तेमाल करने के लिए कहें:

Kotlin

textView.setSpannableFactory(spannableFactory)

Java

textView.setSpannableFactory(spannableFactory);

Spannable.Factory ऑब्जेक्ट को एक बार सेट करें. ऐसा तब करें, जब आपको अपने TextView. अगर RecyclerView का इस्तेमाल किया जा रहा है, तो Factory ऑब्जेक्ट को तब सेट करें, जब व्यू को बढ़ाने में मदद मिलती है. इससे अतिरिक्त ऑब्जेक्ट बनाने से बचा जा सकता है, जब आपके RecyclerView, आपके ViewHolder पर एक नया आइटम बाइंड करता है.

इंटरनल स्पैन एट्रिब्यूट बदलना

अगर आपको किसी बदले जा सकने वाले स्पैन का सिर्फ़ एक इंटरनल एट्रिब्यूट बदलना है, जैसे कि कस्टम बुलेट स्पैन में बुलेट कलर का इस्तेमाल करें. इससे ओवरहेड को कॉल से बचाया जा सकता है बनाए गए स्पैन का रेफ़रंस रखकर, उसे कई बार setText() बार इस्तेमाल करें. जब आपको स्पैन में बदलाव करना हो, तो रेफ़रंस में बदलाव करके, TextView पर invalidate() या requestLayout(). यह इस बात पर निर्भर करता है कि किस तरह के नतीजे दिखाए जा रहे हैं विशेषता बदली गई है.

नीचे दिए गए कोड उदाहरण में, कस्टम बुलेट पॉइंट को लागू करने के तरीके में लाल का डिफ़ॉल्ट रंग जो किसी बटन को टैप किए जाने पर धूसर हो जाता है:

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 एक्सटेंशन फ़ंक्शन का इस्तेमाल करना

Android KTX में ऐसे एक्सटेंशन फ़ंक्शन भी शामिल हैं जो स्पैन के साथ काम करना बनाते हैं और भी आसान हो गया है. ज़्यादा जानने के लिए, androidx.core.text पैकेज.