স্প্যানগুলি শক্তিশালী মার্কআপ অবজেক্ট যা আপনি অক্ষর বা অনুচ্ছেদ স্তরে টেক্সট স্টাইল করতে ব্যবহার করতে পারেন। টেক্সট অবজেক্টে স্প্যান সংযুক্ত করে, আপনি রঙ যোগ করা, টেক্সট ক্লিকযোগ্য করা, টেক্সট সাইজ স্কেল করা এবং কাস্টমাইজড উপায়ে টেক্সট আঁকা সহ বিভিন্ন উপায়ে টেক্সট পরিবর্তন করতে পারেন। স্প্যানগুলি TextPaint
বৈশিষ্ট্যগুলিও পরিবর্তন করতে পারে, একটি Canvas
আঁকতে পারে এবং পাঠ্য বিন্যাস পরিবর্তন করতে পারে।
অ্যান্ড্রয়েড বিভিন্ন ধরণের স্প্যান সরবরাহ করে যা বিভিন্ন সাধারণ পাঠ্য স্টাইলিং প্যাটার্নগুলিকে কভার করে৷ আপনি কাস্টম স্টাইলিং প্রয়োগ করতে আপনার নিজস্ব স্প্যান তৈরি করতে পারেন।
একটি স্প্যান তৈরি করুন এবং প্রয়োগ করুন
একটি স্প্যান তৈরি করতে, আপনি নিম্নলিখিত টেবিলে তালিকাভুক্ত ক্লাসগুলির একটি ব্যবহার করতে পারেন। পাঠ্য নিজেই পরিবর্তনযোগ্য কিনা, পাঠ্য মার্কআপ পরিবর্তনযোগ্য কিনা এবং অন্তর্নিহিত ডেটা কাঠামোতে স্প্যান ডেটা রয়েছে কিনা তার উপর ভিত্তি করে ক্লাসগুলি পৃথক হয়।
ক্লাস | পরিবর্তনযোগ্য পাঠ্য | পরিবর্তনযোগ্য মার্কআপ | ডেটা স্ট্রাকচার |
---|---|---|---|
SpannedString | না | না | লিনিয়ার অ্যারে |
SpannableString | না | হ্যাঁ | লিনিয়ার অ্যারে |
SpannableStringBuilder | হ্যাঁ | হ্যাঁ | ব্যবধান গাছ |
তিনটি ক্লাসই Spanned
ইন্টারফেস প্রসারিত করে। SpannableString
এবং SpannableStringBuilder
এছাড়াও Spannable
ইন্টারফেস প্রসারিত করে।
কোনটি ব্যবহার করবেন তা এখানে কীভাবে সিদ্ধান্ত নেওয়া যায়:
- আপনি যদি তৈরি করার পরে টেক্সট বা মার্কআপ পরিবর্তন না করেন, তাহলে
SpannedString
ব্যবহার করুন। - আপনি যদি একটি একক পাঠ্য বস্তুর সাথে অল্প সংখ্যক স্প্যান সংযুক্ত করতে চান এবং পাঠ্যটি কেবলমাত্র পঠনযোগ্য হয়, তাহলে
SpannableString
ব্যবহার করুন। - আপনি যদি তৈরি করার পরে পাঠ্য পরিবর্তন করতে চান এবং আপনাকে পাঠ্যের সাথে স্প্যান সংযুক্ত করতে হবে,
SpannableStringBuilder
ব্যবহার করুন। - আপনি যদি একটি পাঠ্য বস্তুর সাথে প্রচুর সংখ্যক স্প্যান সংযুক্ত করতে চান, পাঠ্যটি শুধুমাত্র পাঠযোগ্য কিনা তা নির্বিশেষে,
SpannableStringBuilder
ব্যবহার করুন।
একটি স্প্যান প্রয়োগ করতে, একটি Spannable
বস্তুতে setSpan(Object _what_, int _start_, int _end_, int _flags_)
কল করুন। কোন প্যারামিটারটি আপনি পাঠ্যটিতে যে স্প্যানটি প্রয়োগ করছেন তা বোঝায় এবং শুরু এবং শেষ পরামিতিগুলি পাঠ্যের যে অংশটিতে আপনি স্প্যানটি প্রয়োগ করছেন তা নির্দেশ করে৷
আপনি যদি একটি স্প্যানের সীমানার মধ্যে পাঠ্য সন্নিবেশ করেন, স্প্যানটি স্বয়ংক্রিয়ভাবে সন্নিবেশিত পাঠ্য অন্তর্ভুক্ত করতে প্রসারিত হয়। স্প্যান বাউন্ডারিতে টেক্সট ঢোকানোর সময়—অর্থাৎ, শুরু বা শেষ সূচকে— ফ্ল্যাগ প্যারামিটার নির্ধারণ করে যে স্প্যানটি সন্নিবেশিত পাঠ্য অন্তর্ভুক্ত করতে প্রসারিত হবে কিনা। ঢোকানো পাঠ্য অন্তর্ভুক্ত করতে Spannable.SPAN_EXCLUSIVE_INCLUSIVE
পতাকা ব্যবহার করুন এবং ঢোকানো পাঠ্যটি বাদ দিতে Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
ব্যবহার করুন৷SPAN_EXCLUSIVE_EXCLUSIVE৷
নিম্নলিখিত উদাহরণ দেখায় কিভাবে একটি স্ট্রিং একটি ForegroundColorSpan
সংযুক্ত করতে হয়:
কোটলিন
val spannable = SpannableStringBuilder("Text is spantastic!") spannable.setSpan( ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE )
জাভা
SpannableStringBuilder spannable = new SpannableStringBuilder("Text is spantastic!"); spannable.setSpan( new ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE );
কারণ স্প্যানটি Spannable.SPAN_EXCLUSIVE_INCLUSIVE
ব্যবহার করে সেট করা হয়েছে৷ SPAN_EXCLUSIVE_INCLUSIVE , স্প্যানটি স্প্যানের সীমানায় সন্নিবেশিত পাঠ্য অন্তর্ভুক্ত করতে প্রসারিত হয়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
val spannable = SpannableStringBuilder("Text is spantastic!") spannable.setSpan( ForegroundColorSpan(Color.RED), 8, // start 12, // end Spannable.SPAN_EXCLUSIVE_INCLUSIVE ) spannable.insert(12, "(& fon)")
জাভা
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)");
আপনি একই পাঠ্যের সাথে একাধিক স্প্যান সংযুক্ত করতে পারেন। নিচের উদাহরণটি দেখায় যে কীভাবে বোল্ড এবং লাল টেক্সট তৈরি করতে হয়:
কোটলিন
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 )
জাভা
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 android.text.style প্যাকেজে 20টিরও বেশি স্প্যান প্রকার সরবরাহ করে। অ্যান্ড্রয়েড দুটি প্রাথমিক উপায়ে স্প্যানকে শ্রেণীবদ্ধ করে:
- স্প্যান কীভাবে পাঠ্যকে প্রভাবিত করে: একটি স্প্যান পাঠ্যের উপস্থিতি বা পাঠ্য মেট্রিক্সকে প্রভাবিত করতে পারে।
- স্প্যান স্কোপ: কিছু স্প্যান পৃথক অক্ষরগুলিতে প্রয়োগ করা যেতে পারে, অন্যগুলি অবশ্যই একটি সম্পূর্ণ অনুচ্ছেদে প্রয়োগ করতে হবে।
নিম্নলিখিত বিভাগগুলি এই বিভাগগুলিকে আরও বিশদে বর্ণনা করে৷
স্প্যান যা পাঠ্যের চেহারাকে প্রভাবিত করে
অক্ষর স্তরে প্রযোজ্য কিছু স্প্যান পাঠ্যের চেহারাকে প্রভাবিত করে, যেমন পাঠ্য বা পটভূমির রঙ পরিবর্তন করা এবং আন্ডারলাইন বা স্ট্রাইকথ্রু যোগ করা। এই স্প্যানগুলি CharacterStyle
ক্লাস প্রসারিত করে।
নিম্নলিখিত কোড উদাহরণটি দেখায় কিভাবে পাঠ্যকে আন্ডারলাইন করতে একটি UnderlineSpan
প্রয়োগ করতে হয়:
কোটলিন
val string = SpannableString("Text with underline span") string.setSpan(UnderlineSpan(), 10, 19, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
জাভা
SpannableString string = new SpannableString("Text with underline span"); string.setSpan(new UnderlineSpan(), 10, 19, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
যে স্প্যানগুলি শুধুমাত্র পাঠ্যের চেহারাকে প্রভাবিত করে সেগুলি লেআউটের পুনঃগণনা ট্রিগার না করেই পাঠ্যের একটি পুনঃআঁকে ট্রিগার করে। এই স্প্যানগুলি UpdateAppearance
বাস্তবায়ন করে এবং CharacterStyle
প্রসারিত করে। CharacterStyle
সাবক্লাস TextPaint
আপডেট করার অ্যাক্সেস প্রদান করে কীভাবে পাঠ্য আঁকতে হয় তা সংজ্ঞায়িত করে।
স্প্যান যা টেক্সট মেট্রিক্সকে প্রভাবিত করে
অক্ষর স্তরে প্রযোজ্য অন্যান্য স্প্যানগুলি পাঠ্য মেট্রিক্সকে প্রভাবিত করে, যেমন লাইনের উচ্চতা এবং পাঠ্যের আকার। এই স্প্যানগুলি MetricAffectingSpan
ক্লাস প্রসারিত করে।
নিম্নলিখিত কোড উদাহরণটি একটি RelativeSizeSpan
তৈরি করে যা পাঠ্যের আকার 50% বৃদ্ধি করে:
কোটলিন
val string = SpannableString("Text with relative size span") string.setSpan(RelativeSizeSpan(1.5f), 10, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
জাভা
SpannableString string = new SpannableString("Text with relative size span"); string.setSpan(new RelativeSizeSpan(1.5f), 10, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
টেক্সট মেট্রিক্সকে প্রভাবিত করে এমন একটি স্প্যান প্রয়োগ করার ফলে একটি পর্যবেক্ষক বস্তু সঠিক লেআউট এবং রেন্ডারিংয়ের জন্য টেক্সটকে পুনরায় পরিমাপ করতে পারে—উদাহরণস্বরূপ, পাঠ্যের আকার পরিবর্তন করার ফলে শব্দগুলি বিভিন্ন লাইনে প্রদর্শিত হতে পারে। পূর্ববর্তী স্প্যানটি প্রয়োগ করা একটি পুনঃপরিমাপ, পাঠ্য বিন্যাসের পুনঃগণনা এবং পাঠ্যের পুনরায় অঙ্কনকে ট্রিগার করে।
স্প্যানগুলি যেগুলি পাঠ্যের মেট্রিক্সকে প্রভাবিত করে সেগুলি MetricAffectingSpan
ক্লাসকে প্রসারিত করে, একটি বিমূর্ত শ্রেণী যা সাবক্লাসগুলিকে সংজ্ঞায়িত করতে দেয় যে স্প্যানটি TextPaint
এ অ্যাক্সেস প্রদান করে পাঠ্য পরিমাপকে কীভাবে প্রভাবিত করে। যেহেতু MetricAffectingSpan
CharacterSpan
প্রসারিত করে, তাই সাবক্লাসগুলি অক্ষর স্তরে পাঠ্যের উপস্থিতিকে প্রভাবিত করে।
স্প্যান যা অনুচ্ছেদকে প্রভাবিত করে
একটি স্প্যান অনুচ্ছেদ স্তরে পাঠকেও প্রভাবিত করতে পারে, যেমন প্রান্তিককরণ বা পাঠ্যের ব্লকের মার্জিন পরিবর্তন করা। স্প্যান যা সমগ্র অনুচ্ছেদগুলিকে প্রভাবিত করে ParagraphStyle
প্রয়োগ করে। এই স্প্যানগুলি ব্যবহার করতে, আপনি এগুলিকে সম্পূর্ণ অনুচ্ছেদে সংযুক্ত করুন, শেষের নতুন লাইনের অক্ষর বাদ দিয়ে। আপনি যদি সম্পূর্ণ অনুচ্ছেদ ব্যতীত অন্য কিছুতে একটি অনুচ্ছেদ স্প্যান প্রয়োগ করার চেষ্টা করেন, তবে অ্যান্ড্রয়েড স্প্যানটি মোটেও প্রয়োগ করে না।
চিত্র 8 দেখায় কিভাবে Android পাঠ্যের অনুচ্ছেদগুলিকে আলাদা করে।
নিম্নলিখিত কোড উদাহরণ একটি অনুচ্ছেদে একটি QuoteSpan
প্রয়োগ করে। মনে রাখবেন যে আপনি যদি একটি অনুচ্ছেদের শুরু বা শেষ ব্যতীত অন্য যেকোন অবস্থানে স্প্যানটি সংযুক্ত করেন, তবে Android স্টাইলটি মোটেও প্রয়োগ করে না।
কোটলিন
spannable.setSpan(QuoteSpan(color), 8, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
জাভা
spannable.setSpan(new QuoteSpan(color), 8, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
কাস্টম স্প্যান তৈরি করুন
আপনার যদি বিদ্যমান অ্যান্ড্রয়েড স্প্যানগুলিতে সরবরাহ করা হয় তার চেয়ে বেশি কার্যকারিতার প্রয়োজন হয়, আপনি একটি কাস্টম স্প্যান বাস্তবায়ন করতে পারেন৷ আপনার নিজস্ব স্প্যান বাস্তবায়ন করার সময়, আপনার স্প্যানটি অক্ষর স্তরে বা অনুচ্ছেদ স্তরে পাঠ্যকে প্রভাবিত করে কিনা এবং এটি পাঠ্যের বিন্যাস বা চেহারাকে প্রভাবিত করে কিনা তাও সিদ্ধান্ত নিন। এটি আপনাকে কোন বেস ক্লাসগুলি প্রসারিত করতে পারে এবং কোন ইন্টারফেসগুলি বাস্তবায়ন করতে হবে তা নির্ধারণ করতে সহায়তা করে। রেফারেন্সের জন্য নিম্নলিখিত টেবিল ব্যবহার করুন:
দৃশ্যকল্প | ক্লাস বা ইন্টারফেস |
---|---|
আপনার স্প্যান অক্ষর স্তরে পাঠকে প্রভাবিত করে। | CharacterStyle |
আপনার স্প্যান টেক্সট চেহারা প্রভাবিত করে. | UpdateAppearance |
আপনার স্প্যান টেক্সট মেট্রিক্স প্রভাবিত করে। | UpdateLayout |
আপনার স্প্যান অনুচ্ছেদ স্তরে পাঠকে প্রভাবিত করে। | ParagraphStyle |
উদাহরণস্বরূপ, যদি আপনি একটি কাস্টম স্প্যান বাস্তবায়ন করতে চান যা পাঠ্যের আকার এবং রঙ পরিবর্তন করে, RelativeSizeSpan
প্রসারিত করুন। উত্তরাধিকারের মাধ্যমে, RelativeSizeSpan
CharacterStyle
প্রসারিত করে এবং দুটি Update
ইন্টারফেস প্রয়োগ করে। যেহেতু এই ক্লাসটি ইতিমধ্যেই updateDrawState
এবং updateMeasureState
এর জন্য কলব্যাক প্রদান করে, তাই আপনি আপনার কাস্টম আচরণ বাস্তবায়ন করতে এই কলব্যাকগুলিকে ওভাররাইড করতে পারেন৷ নিম্নলিখিত কোডটি একটি কাস্টম স্প্যান তৈরি করে যা RelativeSizeSpan
প্রসারিত করে এবং TextPaint
এর রঙ সেট করতে updateDrawState
কলব্যাককে ওভাররাইড করে:
কোটলিন
class RelativeSizeColorSpan( size: Float, @ColorInt private val color: Int ) : RelativeSizeSpan(size) { override fun updateDrawState(textPaint: TextPaint) { super.updateDrawState(textPaint) textPaint.color = color } }
জাভা
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
সংযুক্ত করে। নিম্নোক্ত কোডের উদাহরণটি দেখায় যে বুলেট পয়েন্টগুলি প্রত্যাশিতভাবে প্রদর্শিত হবে কিনা তা পরীক্ষা করতে হবে:
কোটলিন
@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()) }
জাভা
@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 পরীক্ষা প্রয়োগ করে এই শ্রেণীর আচরণ পরীক্ষা করতে পারেন, নিম্নলিখিতগুলি পরীক্ষা করে:
- আপনি সঠিকভাবে স্প্যান প্রয়োগ করলে, ক্যানভাসে নির্দিষ্ট আকার এবং রঙের একটি বুলেট পয়েন্ট প্রদর্শিত হবে এবং বাম মার্জিন এবং বুলেট পয়েন্টের মধ্যে সঠিক স্থান বিদ্যমান থাকবে।
- আপনি স্প্যান প্রয়োগ না করলে, কাস্টম আচরণের কোনোটিই প্রদর্শিত হবে না।
আপনি GitHub এ TextStyling নমুনায় এই পরীক্ষার বাস্তবায়ন দেখতে পারেন।
আপনি ক্যানভাসকে উপহাস করে, উপহাস করা বস্তুটিকে drawLeadingMargin()
পদ্ধতিতে পাস করে এবং সঠিক প্যারামিটারের সাথে সঠিক পদ্ধতিগুলিকে কল করা হয়েছে তা যাচাই করে ক্যানভাসের মিথস্ক্রিয়া পরীক্ষা করতে পারেন।
আপনি BulletPointSpanTest- এ আরও স্প্যান পরীক্ষার নমুনা খুঁজে পেতে পারেন।
স্প্যান ব্যবহার করার জন্য সর্বোত্তম অনুশীলন
আপনার প্রয়োজনের উপর নির্ভর করে TextView
এ পাঠ্য সেট করার জন্য বেশ কিছু মেমরি-দক্ষ উপায় রয়েছে।
অন্তর্নিহিত পাঠ্য পরিবর্তন না করে একটি স্প্যান সংযুক্ত করুন বা বিচ্ছিন্ন করুন৷
TextView.setText()
একাধিক ওভারলোড রয়েছে যা স্প্যানগুলিকে ভিন্নভাবে পরিচালনা করে। উদাহরণস্বরূপ, আপনি নিম্নলিখিত কোড সহ একটি Spannable
পাঠ্য বস্তু সেট করতে পারেন:
কোটলিন
textView.setText(spannableObject)
জাভা
textView.setText(spannableObject);
setText()
এর এই ওভারলোডটিকে কল করার সময়, TextView
আপনার Spannable
এর একটি SpannedString
হিসাবে একটি অনুলিপি তৈরি করে এবং এটিকে একটি CharSequence
হিসাবে মেমরিতে রাখে। এর মানে হল যে আপনার পাঠ্য এবং স্প্যানগুলি অপরিবর্তনীয়, তাই যখন আপনাকে পাঠ্য বা স্প্যানগুলি আপডেট করতে হবে, একটি নতুন Spannable
অবজেক্ট তৈরি করুন এবং আবার setText()
কল করুন, যা লেআউটের পুনরায় পরিমাপ এবং পুনরায় অঙ্কন শুরু করে।
স্প্যানগুলি অবশ্যই পরিবর্তনযোগ্য হতে হবে তা নির্দেশ করার জন্য, আপনি পরিবর্তে setText(CharSequence text, TextView.BufferType type)
ব্যবহার করতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
textView.setText(spannable, BufferType.SPANNABLE) val spannableText = textView.text as Spannable spannableText.setSpan( ForegroundColorSpan(color), 8, spannableText.length, SPAN_INCLUSIVE_INCLUSIVE )
জাভা
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()
কল করুন।
একটি TextView এ একাধিকবার পাঠ্য সেট করুন
কিছু ক্ষেত্রে, যেমন একটি RecyclerView.ViewHolder
ব্যবহার করার সময়, আপনি একটি TextView
পুনরায় ব্যবহার করতে এবং পাঠ্যটি একাধিকবার সেট করতে চাইতে পারেন। ডিফল্টরূপে, আপনি BufferType
সেট করুন না কেন, TextView
CharSequence
অবজেক্টের একটি অনুলিপি তৈরি করে এবং এটি মেমরিতে ধরে রাখে। এটি সমস্ত TextView
আপডেটগুলিকে ইচ্ছাকৃত করে তোলে- আপনি পাঠ্যটি আপডেট করতে মূল CharSequence
অবজেক্ট আপডেট করতে পারবেন না। এর মানে আপনি যখনই নতুন টেক্সট সেট করেন, TextView
একটি নতুন অবজেক্ট তৈরি করে।
যদি এই প্রক্রিয়াটির উপর আরও নিয়ন্ত্রণ নিতে চান এবং অতিরিক্ত বস্তু তৈরি এড়াতে চান, আপনি নিজের Spannable.Factory
বাস্তবায়ন করতে পারেন এবং newSpannable()
ওভাররাইড করতে পারেন। একটি নতুন টেক্সট অবজেক্ট তৈরি করার পরিবর্তে, আপনি বিদ্যমান CharSequence
Spannable
হিসেবে কাস্ট এবং ফেরত দিতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
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
ব্যবহার করতে বলুন:
কোটলিন
textView.setSpannableFactory(spannableFactory)
জাভা
textView.setSpannableFactory(spannableFactory);
একবার Spannable.Factory
অবজেক্ট সেট করুন, আপনি আপনার TextView
এর রেফারেন্স পাওয়ার পরেই। আপনি যদি RecyclerView
ব্যবহার করেন, আপনি যখন প্রথম আপনার দৃষ্টিভঙ্গি স্ফীত করবেন তখন Factory
অবজেক্ট সেট করুন। যখন আপনার RecyclerView
আপনার ViewHolder
একটি নতুন আইটেম আবদ্ধ করে তখন এটি অতিরিক্ত অবজেক্ট তৈরিকে এড়িয়ে যায়।
অভ্যন্তরীণ স্প্যান বৈশিষ্ট্য পরিবর্তন করুন
আপনি যদি একটি পরিবর্তনযোগ্য স্প্যানের শুধুমাত্র একটি অভ্যন্তরীণ বৈশিষ্ট্য পরিবর্তন করতে চান, যেমন একটি কাস্টম বুলেট স্প্যানে বুলেটের রঙ, আপনি স্প্যানটি তৈরি হওয়ার সাথে সাথে একটি রেফারেন্স রেখে setText()
একাধিকবার কল করা থেকে ওভারহেড এড়াতে পারেন। আপনি যখন স্প্যানটি পরিবর্তন করতে চান, তখন আপনি রেফারেন্সটি পরিবর্তন করতে পারেন এবং তারপরে আপনার পরিবর্তিত বৈশিষ্ট্যের ধরণের উপর নির্ভর করে TextView
এ invalidate()
বা requestLayout()
কল করতে পারেন।
নিম্নলিখিত কোড উদাহরণে, একটি কাস্টম বুলেট পয়েন্ট বাস্তবায়নের একটি ডিফল্ট রঙ লাল থাকে যা একটি বোতামে ট্যাপ করা হলে ধূসর হয়ে যায়:
কোটলিন
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() } } }
জাভা
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(); } }); } }
অ্যান্ড্রয়েড কেটিএক্স এক্সটেনশন ফাংশন ব্যবহার করুন
অ্যান্ড্রয়েড কেটিএক্সে এক্সটেনশন ফাংশনও রয়েছে যা স্প্যানগুলির সাথে কাজ করা সহজ করে তোলে। আরও জানতে, androidx.core.text প্যাকেজের ডকুমেন্টেশন দেখুন।