Typeface — এটি android.graphics প্যাকেজের Android SDK এর একটি ক্লাস যা ফন্টের ডিজাইন উপস্থাপন করে এবং TextView ও অন্যান্য UI উপাদানে টেক্সট কাস্টমাইজেশনের জন্য ব্যবহৃত হয়। Typeface ফন্ট পরিবার, এর ওজন (normal, bold) এবং শৈলী (normal, italic) সংজ্ঞায়িত করে। Google Developers অনুযায়ী, Typeface TTF, OTF ফাইল, XML ফন্ট এবং সিস্টেম রিসোর্স থেকে লোডিং সমর্থন করে। এটি Android অ্যাপ্লিকেশনে টাইপোগ্রাফি পরিচালনার জন্য কেন্দ্রীয় ক্লাস।
মূল বিষয়সমূহ
Typeface — একটি Android ক্লাস যা ফন্ট তথ্য এনকাপসুলেট করে: এর পরিবার (Roboto, Arial, Serif) ও শৈলী পরিবর্তক (bold, italic)। iOS এ UIFont এর বিপরীতে, Typeface আকার তথ্য ধারণ করে না — টেক্সটের আকার TextView এ textSize প্রপার্টি বা Spannable এ TextStyle এর মাধ্যমে আলাদাভাবে সেট করা হয়। Typeface কেবল ফন্টের ডিজাইন ও পরিবারের জন্য দায়ী।
ক্লাসটি সব API স্তরে উপলব্ধ। Android 4.4 এর আগে, Typeface কেবল সীমিত সিস্টেম ফন্ট সমর্থন করত: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF। Android 8.0 (API 26) থেকে শুরু করে, XML রিসোর্সের মাধ্যমে কাস্টম ফন্ট লোডিং সমর্থন যোগ করা হয়েছে, এবং Android 10 ভেরিয়েবল ফন্ট সমর্থন যোগ করেছে।
Android একাধিক নির্মিত Typeface ইনস্টেন্স প্রদান করে: Typeface.DEFAULT — সিস্টেম ফন্ট Roboto (Material) বা Noto (AOSP), DEFAULT_BOLD — বোল্ড সংস্করণ, MONOSPACE — কোডের জন্য মোনোস্পেস ফন্ট, SERIF — সেরিফ ফন্ট (Noto Serif), SANS_SERIF — স্যান্স-সেরিফ (Noto Sans)। এই স্থিরাংকগুলি কন্টেক্সট ছাড়াই উপলব্ধ এবং ফাইল পড়ার অনুমতির প্রয়়োজন নেই।
Android সিস্টেম সকল টেক্সট রেন্ডারের জন্য Typeface ব্যবহার করে, যার মধ্যে সিস্টেম UI, শিরোনাম, ক্যাপশন ও বিজ্ঞপ্তি অন্তর্ভুক্ত। প্রতিটি অ্যাপ্লিকেশন থিম (android:fontFamily) বা প্রোগ্রামাটিকভাবে setTypeface() এর মাধ্যমে ডিফল্ট ফন্ট অতিক্রম করতে পারে। Typeface TextView থেকে উদ্ভূত সকল উপাদানে প্রয়োজ্য: বটন, EditText ও কাস্টম ভিউ।
Android 8.0+ res/font এ ফন্ট যোগ করার এবং XML রিসোর্সের মাধ্যমে ব্যবহারের অনুমতি দেয়। ফন্ট ফাইল (TTF বা OTF) res/font এ রাখা হয়, যার পর R.font.font_name রিফারেন্স তৈরি করা হয়। Typeface লোড করা হয় ResourcesCompat.getFont(context, R.font.font_name) এর মাধ্যমে। এই পদ্ধতিটি পছন্দযোগ্য কারণ ফন্ট APK এ কম্পাইল হয় এবং ProGuard বিল্ড সিস্টেম সমর্থন করে।
রিসোর্স পদ্ধতি res/font এ XML ফাইলের মাধ্যমে ফন্ট পরিবার ও সমর্থন করে: আপনি বিভিন্ন ডিজাইন (regular, bold, italic) এর জন্য একাধিক ফাইল নির্দিষ্ট করতে পারেন এবং setTypeface কল করার সময় সিস্টেম স্বয়ংক্রিয়ভাবে উপযুক্ত ফাইল নির্বাচন করবে। এটি টাইপোগ্রাফি সরল করে — থিমে fontFamily সেট করুন, এবং Android স্বয়ংক্রিয়ভাবে সঠিক ফাইল নির্বাচন করবে।
Typeface.create(Typeface family, int style) পদ্ধতিটি নির্দিষ্ট পরিবার ও শৈলী সহ একটি ফন্ট ইনস্টেন্স তৈরি করে। যদি পরিবারের ইতিমধ্যেই অনুরোধিত শৈলী থাকে, তবে বিদ্যমান ইনস্টেন্স ফেরত দেওয়া হয়। যদি শৈলী উপস্থিত না থাকে, তবে Android এটি সিন্থেসাইজ করে — বেস ফন্টে নকলি বোল্ড বা কৃত্রিম ইটালিক প্রয়োগ করে।
val boldTypeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD)
val italicTypeface = Typeface.create(Typeface.MONOSPACE, Typeface.ITALIC)
val customTypeface = ResourcesCompat.getFont(context, R.font.montserrat_regular)
textView.typeface = boldTypeface
সিন্থেসাইজড নকলি বোল্ড পাতলা ফন্টে নিম্নমানের হতে পারে। উৎতম ফলাফলের জন্য, প্রকৃত bold ডিজাইন সহ একটি ফন্ট ফাইল ব্যবহার করুন। Typeface.create() অবিদ্যমান শৈলীর সাথে কোন ব্যতিক্রম ছাড়ে না, বরং নিকটবর্তী উপলব্ধ বিকল্প ফেরত দেয়।
assets থেকে Typeface লোড করার জন্য Typeface.createFromAsset(assetManager, path) ব্যবহার করুন। ফন্টটি src/main/assets/fonts/ ডিরেক্টরিতে রাখা হয়, এবং পাথটি assets এর সাপেক্ষে নির্দিষ্ট করা হয়। এই পদ্ধতিটি Android এর সকল সংস্করণে কাজ করে, কিন্তু ফন্ট পরিবার সমর্থন করে না এবং প্রতিটি ডিজাইনের জন্য একটি নির্দিষ্ট ফাইল নির্দিষ্ট করা প্রয়়োজন।
Typeface.createFromFile(File) পদ্ধতিটি ফাইল সিস্টেমে যেকোনো ফাইল থেকে একটি ফন্ট লোড করে। এটি নেটওয়ার্ক থেকে ডাউনলোড করা বা অ্যাপ্লিকেশনের অন্তরিক স্টোরেজে কপি করা ফন্টের জন্য দরকারী। createFromFile এর জন্যও কন্টেক্সট প্রয়়োজন নেই, যা ব্যাকগ্রাউন্ড কাজের জন্য সুবিধাজনক, কিন্তু ফাইলটি পড়া যোগ্য হতে হবে।
createFromAsset এর মাধ্যমে বারবার Typeface লোড করা ডাপ্লিকেট অবজেক্ট তৈরির কারণ হতে পারে। প্রতিটি createFromAsset কল ফাইলটি পুনরায় লোড করে। HashMap ব্যবহার করে Typeface ক্যাশ বাস্তবায়ন করার পরামর্শ দেওয়া হয়, যেখানে কী ফাইল পাথ এবং মান লোড করা ইনস্টেন্স। এটি বিশেষ করে বিভিন্ন ফন্ট ধরনের তালিকার জন্য গুরুত্বপূর্ণ।
object TypefaceCache {
private val cache = mutableMapOf<String, Typeface>()
fun getTypeface(context: Context, filename: String): Typeface {
return cache.getOrPut(filename) {
Typeface.createFromAsset(context.assets, "fonts/$filename")
}
}
}
// Usage
val typeface = TypefaceCache.getTypeface(context, "Roboto-Bold.ttf")
মেমরিতে ক্যাশ নিশ্চিত করে যে একটি ফন্ট অ্যাপ্লিকেশন সাটে প্রতি কেবল একবার লোড হয়। কনফিগারেশন পরিবর্তন (স্ক্রিন ঘূর্ণন) এ ক্যাশ টিকে থাকে কারণ এটি একটি companion অবজেক্টে অবস্থিত। স্বল্প মেমরিতে ক্যাশ পরিষ্কার করার জন্য, WeakHashMap ব্যবহার করুন বা onTrimMemory শুনুন।
Typeface TextView এ setTypeface(Typeface tf) বা setTypeface(Typeface tf, int style) পদ্ধতির মাধ্যমে প্রয়োগ করা হয়। দ্বিতীয় বিকল্পটি বর্তমান ফন্টের সাপেক্ষে শৈলী (bold/italic) পরিবর্তনের অনুমতি দেয়। XML এ, android:fontFamily এট্রিবিউট ফন্ট বা সিস্টেম পরিবারের রিফারেন্স সহ ব্যবহৃত হয়। প্রোগ্রামাটিক সেটাপের জন্য, setTypeface(monospaceTypeface) কল করা ফন্টটিকে নির্দিষ্টটি দিয়ে প্রতিস্থাপন করে।
Typeface সম্পূর্ণ TextView লিখন প্রভাবিত করে। যদি একটি লাইনে বিভিন্ন ফন্ট প্রয়়োজন হয়, তবে TypefaceSpan সহ SpannableString ব্যবহার করুন। TypefaceSpan Typeface বা পরিবার গ্রহণ করে এবং একটি অক্ষর পরিসরে প্রয়োগ করা হয়। নেস্টেড উপাদান ছাড়া একটি TextView এর মধ্যে ফন্ট মিশানোর এটি একমাত্র উপায়।
TypefaceSpan কেবল স্ট্রিংয়ের একটি অংশে প্রয়োগ করুন। উদাহরণস্বরূপ, লিখনে একটি ভেরিয়েবলের মান মোনোস্পেস হওয়া উচিত যতক্ষণ বাকি লিখন সিস্টেম ফন্টে থাকে। একটি SpannableString তৈরি করুন এবং MONOSPACE Typeface সহ TypefaceSpan ইচ্ছিত পরিসরে সেট করুন। বাকি লিখন মূল TextView ফন্টে থাকে।
val text = "Code: variableName"
val spannable = SpannableString(text)
spannable.setSpan(
TypefaceSpan(Typeface.MONOSPACE),
5, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
spannable.setSpan(
ForegroundColorSpan(Color.BLUE),
5, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannable
লিখনটি “variableName” নীল রঙের মোনোস্পেস ফন্টে দেখাবে, যতক্ষণ শব্দ “Code:” সিস্টেম ফন্টে থাকবে। TypefaceSpan কে যেকোনো অন্য স্প্যানের সাথে যুক্ত করা যেতে পারে লিখনের প্রতিটি অংশের উপর সটিক নিয়ন্ত্রণের জন্য।
Android বেশ কয়েকটি ফন্ট ফরম্যাট সমর্থন করে: TrueType (TTF), OpenType (OTF) এবং Web Open Font Format (WOFF2) Android 10 থেকে শুরু হয়। TTF এবং OTF কাস্টম ফন্টের জন্য প্রধান ফরম্যাট। XML ফন্ট (Font Family) একটি পৃথক ফরম্যাট নয়, বরং প্রতিটি ডিজাইনের জন্য কোন ফাইল ব্যবহার করতে হবে তার বর্ণনা হিসেবে কাজ করে।
res/font এর মাধ্যমে কাস্টম ফন্ট ব্যবহারের জন্য, একটি পরিবার XML ফাইল তৈরি করুন যা regular, bold এবং italic এর জন্য ফন্ট ফাইলের পাথ নির্দিষ্ট করে। তারপর অ্যাপ্লিকেশন থিমে, android:fontFamily="@font/custom_family" নির্দিষ্ট করুন। এই থিম ব্যবহার করা সকল TextView ইনস্টেন্স স্বয়ংক্রিয়ভাবে প্রতিটি শৈলীর জন্য সঠিক ডিজাইন পাবে।
যদি একটি ফন্ট নেটওয়ার্ক থেকে ডাউনলোড করা হয়, তবে এটি filesDir বা cacheDir এ সংরক্ষণ করুন এবং Typeface.createFromFile এর মাধ্যমে লোড করুন। লোড করার পর, TextView এ Typeface আপডেট করুন। অ্যাসিংক্রোনাস লোডিংয়ের জন্য, coroutine বা DownloadManager ব্যবহার করুন, এবং সমাপ্তির পর Handler এর মাধ্যমে UI থ্রেডে পোস্ট করুন। এটি চাহিদা অনুসারে লোড করা কাস্টম টাইপোগ্রাফি সহ অ্যাপ্লিকেশনের জন্য একটি সাধারণ পরিদৃশ্য।
// Save font file to internal storage
val fontFile = File(context.cacheDir, "downloaded-font.otf")
fontFile.outputStream().use { output ->
// inputStream from network
inputStream.copyTo(output)
}
// Create Typeface from file
val downloadedTypeface = Typeface.createFromFile(fontFile)
textView.typeface = downloadedTypeface
লোড করার আগে, ফাইলের উপলব্ধতা যাচাই করুন: যদি ফাইলটি দূষিত বা অবৈধ হয়, তবে Typeface.createFromFile একটি RuntimeException ছুড়ে। কলটিকে try-catch এ মুড়িয়ে ফেলার এবং ত্রুটির ক্ষেত্রে ডিফল্ট সিস্টেম ফন্টে ফিরে যাওয়ার পরামর্শ দেওয়া হয়।
Jetpack Compose এ, Android SDK এর Typeface সরাসরি ব্যবহৃত হয় না। এর পরিবর্তে, Compose টাইপোগ্রাফির জন্য FontFamily এবং FontWeight প্রদান করে। FontFamily লোড করা হয় Font.Resource এবং Font.File এর মাধ্যমে। Compose এর টাইপোগ্রাফি সিস্টেম MaterialTheme.typography এর মাধ্যমে সংজ্ঞায়িত হয়, যেখানে প্রতিটি শৈলী (h1, body1, button) একটি কাস্টম FontFamily নির্দিষ্ট করা যেতে পারে।
রিসোর্স থেকে একটি ফন্ট লোড করার জন্য, Compose Font(R.font.font_name, weight, style) ব্যবহার করে। assets থেকে একটি ফন্ট Font(assetPath = "fonts/custom.otf", weight, style) এর মাধ্যমে লোড করা হয়। ফন্ট সংজ্ঞায়িত করার পর, এটি Typography এ পাঠানো হয়, এবং তারপর MaterialTheme.typography.bodyLarge এবং অনুরূপ শৈলীর মাধ্যমে প্রয়োগ করা হয়।
যদি আপনার কাছে Android SDK এর মাধ্যমে তৈরি একটি বিদ্যমান Typeface থাকে, তবে এটি Compose এ TypefaceAdapter এর মাধ্যমে বা Typeface এর উপর ভিত্তি করে FontFamily তৈরি করে ব্যবহার করা যেতে পারে। Typeface.create থেকে Typeface প্রাপ্ত করুন এবং FontFamily.Custom(listOf(Font(typeface))) এ পাঠানুন। তবे, Font.Resource এর সাথে দেশী পদ্ধতিটি সুপারিশ করা হয় কারণ এটি Compose এর জন্য উৎকৃষ্ট।
ফাইল থেকে ফন্ট লোড করা একটি সম্ভাবিত ব্যয়বহুল কাজ। Typeface.createFromAsset বা Typeface.createFromFile এ প্রতিটি কল ডিস্ক থেকে ফাইল পড়ে, এটি পার্স করে এবং একটি Typeface অবজেক্ট তৈরি করে। 1-2 MB এর ফন্টের জন্য, কোল্ড স্টার্টে এটি 10-50 মিলিসেকেন্ড সময় নেয়। কাস্টম ফন্ট সহ অ্যাপ্লিকেশনের জন্য Typeface ক্যাশিং একটি বাধ্যতামূলক অভ্যাস।
Android SDK createFromAsset বা createFromFile এর মাধ্যমে তৈরি করা ফন্ট ক্যাশ করে না। সিস্টেম ফন্টের বিপরীতে, যা Zygote প্রক্রিয়ায় প্রিলোড করা হয়, কাস্টম ফন্ট প্রতিটি অ্যাক্সেসে লোড করা হয়। একটি ফন্ট শনাক্তকারী হিসেবে LruCache বা ConcurrentHashMap ব্যবহার করার পরামর্শ দেওয়া হয়। 10-20 ইনস্টেন্সের একটি ক্যাশ আকার একটি সাধারণ অ্যাপ্লিকেশন ফন্ট সেট কাভার করে।
Android 8.0+ XML Font Family এর মাধ্যমে ফন্ট লোডিং অপ্টিমাইজ করে। XML লেআউটে android:fontFamily="@font/my_family" নির্দিষ্ট করার সময়, Android ফন্টটি অলসভাবে লোড করে — কেবল যখন উপাদানটি দৃশ্যমান হয়। সিস্টেমটি ResourcesCompat.getFont() এর মাধ্যমে লোড করা ফন্টগুলিকে একটি বৈশ্বিক প্রক্রিয়া ক্যাশে সংরক্ষণ করে। এটি রিসোর্স পদ্ধতিকে সবচেয়ে কর্মদক্ষ করে তোলে।
RecyclerView এডাপ্টারে Typeface ব্যবহার করার সময় onBindViewHolder পদ্ধতিতে ফন্ট না লোড করা গুরুত্বপূর্ণ। এডাপ্টার তৈরির সময় একবার লোড করুন বা একটি প্রিলোড করা Typeface সহ ViewHolder ব্যবহার করুন। যদি প্রতিটি তালিকা আইটেমের একটি অনন্য ফন্ট প্রয়়োজন হয়, তবে WeakHashMap ব্যবহার করে একটি ক্যাশ বাস্তবায়ন করুন এবং মেমরি বাঁচাতে দৃশ্যমান অবস্থানগুলি অতিক্রম করে স্ক্রল করার সময় এটি পরিষ্কার করুন।
সামন্য প্রশ্নাবলী
Typeface — প্রোগ্রামাটিক ব্যবহারের জন্য একটি নির্দিষ্ট ফন্ট ইনস্টেন্স। FontFamily — একটি XML রিসোর্স যা বিভিন্ন ডিজাইন (regular, bold, italic) এর জন্য ফন্ট ফাইলের একটি দল বর্ণনা করে। রানটাইমে, FontFamily ResourcesCompat.getFont এর মাধ্যমে Typeface এ রূপান্তরিত হয়। FontFamily এর মধ্য না গিয়ে Typeface সরাসরি একটি ফাইল থেকে তৈরি করা যেতে পারে।
Typeface.createFromFile(File) বা Typeface.DEFAULT ব্যবহার করুন। এই পদ্ধতিগুলির কন্টেক্সট প্রয়়োজন নেই কারণ এগুলি ফাইল সিস্টেম বা নির্মিত স্থিরাংকের সাথে কাজ করে। assets বা রিসোর্স থেকে লোড করার জন্য, কন্টেক্সট প্রয়়োজন কারণ AssetManager এবং অ্যাপ্লিকেশন রিসোর্সে প্রবেশাধিকার প্রয়়োজন।
না, WebView ফন্ট নির্দিষ্টের জন্য CSS font-family বৈশিষ্ট্য ব্যবহার করে। WebView এ একটি কাস্টম ফন্ট ব্যবহার করার জন্য, ফন্ট ফাইলটি assets এ রাখুন এবং CSS এ @font-face এর মাধ্যমে নির্দিষ্ট করুন। Typeface Android SDK কেবল দেশী UI উপাদান (TextView এবং এর বঙ্শজ) এর সাথে কাজ করে।
হ্যাঁ, Android 10 (API 29) থেকে শুরু করে। ভেরিয়েবল ফন্ট ResourcesCompat.getFont বা Typeface.createFromFile এর মাধ্যমে লোড করা হয়। ভিন্নতা অক্ষ (weight, width) কনফিগার করার জন্য, Compose এ FontStyle বা XML এট্রিবিউট ব্যবহার করুন। প্রোগ্রামাটিকভাবে অক্ষ পরিবর্তন কেবল Skia এর নিম্ন-স্তরের API এর মাধ্যমে করা যেতে পারে।
সবচেয়ে সাধারণ কারণ: প্রকল্পে ফন্ট ফাইলটি উপস্থিত নেই, ফাইলের নাম ভুল, ফন্টটি দূষিত, বা ফাইলে বিদ্যমান নেই যা সিন্থেসাইজড শৈলী ব্যবহৃত হচ্ছে। যাচাই করুন যে ফাইলটি res/font বা assets এ যোগ করা হয়েছে, এবং রিসোর্স পদ্ধতির ক্ষেত্রে এর নাম এক্সটেনশন ছাড়া নির্দিষ্ট করা হয়েছে।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন