استارت‌آپ و کارآفرینی

Calligraphy راه حلی برای تغییر فونت در اندروید

معمولا برای برنامه‌نویسان اندروید پیش اومده که بخواهند فونت برنامه رو به یه فونت فارسی تبدیل کنند و ظاهر برنامه‌شون رو با این کار قشنگ‌تر کنند. در آخرین کاری که انجام دادم به صورت نازیبایی همه TextView ،Button و … رو با استفاده از تابع setTypeface براشون فونت قرار دادم. دیگه بماند که نتونستم عنوان ActionBar و همچنین فونت Toastهای برنامه و چند المان دیگه رو عوض کنم.

گوگل کردم تا ببینم چه راه حل ساده‌تری وجود داره که خیلی زود Calligraphy رو پیدا کردم. در عنوان این کتابخانه در Github نوشته شده که راه حل ساده‌ای برای یک فونت دلخواه است. در ادامه متوجه خواهید شد که بله، واقعا ساده‌ست.
اول از همه خط زیر رو به build.gradle اضافه کنید:

compile 'uk.co.chrisjenx:calligraphy:2.1.0'

بزارید که gradle کار sync رو تموم کنه.

بعدش فونت مورد نظرتون رو به پوشه assets/ اضافه کنید. برای مثال من فونت IRANSansLight.ttf رو به پوشه fonts داخل پوشه assets اضافه کردم. اگر برنامه‌تون کلاس Application داره که بهتر، اگر نداره کلاس رو درست کنید. من کلاس MyApplication رو ایجاد کردم:

public class MyApplication extends Application {

بعدش داخل تابع onCreate این سه خط رو اضافه کنید:

CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
      .setDefaultFontPath("fonts/IRANSansLight.ttf")
      .setFontAttrId(R.attr.fontPath).build());

باید توی AndroidManifest کلاس MyApplication رو بهش معرفی کنید:

<application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@mipmap/icon"
    android:theme="@style/AppTheme"

تقریبا کارمون تموم شده.
الان فقط باید در تمامی Activity برنامه خطوط زیر رو اضافه کنیم و تابع attachBaseContext رو به صورت زیر Override کنیم. مثلا به آخر کد Activity تابع زیر رو اضافه می‌کنیم:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

تموم شد. برنامه‌تون رو اجرا کنید و از تغییراتی که به این سرعت پیدا کرده، لذت ببرید.

Calligraphy

چند نکته:

با این کار همه فونت‌‌های المان‌های برنامه رو عوض می‌کنید. (البته بعضی از کتابخانه‌هایی که به برنامه اضافه کردید ممکنه عوض نشه!!) شاید بخواید برای یک المان خاص یک فونت متفاوت قرار بدید، برای این کار مثلا برای یک TextView می‌تونید به این صورت داخل فایل Layout مورد نظر مقدار fontPath رو بهش اضافه کنید:

<TextView
    android:text="@string/hello_world"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    fontPath="fonts/Roboto-Bold.ttf"/>

با استفاده از پارامتر fontPath مسیر فایل فونت متمایز رو وارد کنید و بقیه کار رو به کتابخانه واگذار کنید.
امکان تعریف فونت برای Style و Themeها هم وجود داره که مثلا با تغییر تم برنامه فونت برنامه به کل عوض بشه. می‌تونید برای بررسی و دیدن امکانات دیگه ش به لینک کتابخانه مراجعه کنید.

22 نظرات
  1. علی می گوید

    دستت درد کنه بهروز

    1. علی می گوید

      منظورم نکنه بود.

  2. محمد می گوید

    عالی بود فقط اگه میشه یه اموزش و راهنمایی در مورد طراحی ui پیشرفته توضیح بدین به این صورت وقتی یه طرح داخل فتوشاپ زده میشه اون طرح رو با چه سایزی برش بدیم و در xml قرار بدیم

    1. بهروز خضری می گوید

      برای اینکه بتونید طراحی بهتر و برای اندازه های مختلف صفحه ارائه بدید بهتره این لینک رو مطالعه کنید
      http://goo.gl/cMGs

  3. عباس می گوید

    واقعا ممنون
    بسیار مفید بود

  4. مهیار می گوید

    عالی بود درست وسط یه پروژه در حالی که داشتم کله ام رو به دیوار می زدم اومدم شروع کردم به خوندن مطالب hive بعدش چی عالی عالی یه مطلب که بدرد می خوره !

  5. طه می گوید

    سلام من طبق مقاله مو به مو انجام دادم نمی دونم کجای کار اشتباهه
    بعد از انجام تمام مراحل در اخر این کد رو به TextView اضافه کردم
    fontPath=”fonts/IranianSans.ttf”
    که خطای
    (Attribute is missing the Android namespace prefix less… (Ctrl+F1
    Most Android views have attributes in the Android namespace. When referencing these attributes you must include the namespace prefix, or your attribute will be interpreted by aapt as just a custom attribute. Similarly, in manifest files, nearly all attributes should be in the android: namespace.
    که به نظرم میگه android: رو به اولش اضافه کن که انجام میدم ولی فرقی نمیکنه
    دوستانی که انجام دادن کمک کنن
    ممنون

    1. بهروز خضری می گوید

      این دو خط رو به تعریف layout تون به parent اصلی مثلا relativelayout اضافه کنید:
      xmlns:android=”http://schemas.android.com/apk/res/android”
      xmlns:tools=”http://schemas.android.com/tools”

      1. طاها قاسمی می گوید

        سلام ممنون از راهنمایی
        البته من حساست اندروید استودیو رو کاهش دادم دیگه اون خطا رو نداد و تونستم از فونت استفاده کنم.

  6. مصطفی نصیری می گوید

    بسیار عالی بود واقعا لذت بردم
    با آرزوی موفقیت روزافزون برای شما

  7. I.M.A.N می گوید

    بسیار خوب .. . ممنون از راهنمایی های خوبتون . . . موفق باشی

  8. عادل می گوید

    سلام
    این کتابخونه فونت TabHeader ها و فیلدهایی که در CustomListViewItem قرار دارند (مثل یک TextView) رو تغییر نمیده.
    لطفا اگر کسی تست کرده و جواب گرفته ما رو هم در جریان بذاره شاید من اشتباه می کنم.

    1. بهروز خضری می گوید

      سلام،
      بله درست می‌فرمایید. توو متن هم ذکر کردم که بعضی از کتابخانه‌ها رو نمی‌تونه تغییر بده.
      در بخش issue کتابخانه، دنبال راهنمایی بگردید.

      1. عادل می گوید

        سلام مجدد.
        ممنون جناب بابت راهنمایی.

  9. Hossein می گوید

    سلام، من زیاد وارد نیستم، ولی وقتی که توی Activity این کارو میکنم فونت تغییر میکنه ولی تو AppCompatActivity فورس کلوز میده
    اگه میشه راهنمایی کنید
    ممنون

    1. بهروز خضری می گوید

      سلام،
      اول مطمئن بشید که خطا از این Calligraphy هست. اگه ممکنه LogCat خطا رو بفرستید.

      1. Hossein می گوید

        بله خوب دوتا پروژه ساختم یکی AppCompatActivity و یکی Activity رو دومی جواب داد
        و وقتی کد رو از AppCompatActivity پاک میکنم میاد
        و مطمئنم که مشکل ازCalligraphy هست
        اگه میشه شما توی پروژه ای که AppCompatActivity باشه امتحان کنید ببینید اصلا این لایبری این قابلیتو داره خیلی ممنون

        1. بهروز خضری می گوید

          بله تستش کردم و دقیقا کار می‌کنه. کاش خطای LogCatش رو می‌فرستادید

  10. احمد می گوید

    سلام، سپاس از آموزشی که گذاشتید
    من مشکلی دارم و این است که من در مانیفست یک android:name دارم، و بخوام یک android:name دیگه اضافه کنم به مشکل بر میخورم،
    ممنون میشم راهنمایی کنید برای رفع مشکل
    با تشکر

    1. بهروز خضری می گوید

      سلام، ببینید این لینک میتونه بهتون کمک کنه
      http://stackoverflow.com/questions/13949666/how-to-register-application-class-in-my-manifest-file

  11. آناهیتا می گوید

    خدا خیرتون بدددددده…..مررررررررررررررسی

  12. sina می گوید

    با سلام و خسته نباشید ممنون بابت توضیحاتتون.
    من ازین لایبرری برای زبان انگلیسی که استفاده میکنم درست کار میکنه اما وقتی که یه فونت فارسی جایگزین کردم و آدرس دهی کردم دیگه فونت تغییری نمیکنه! اروری هم ندارم متوجه نمیشم چرا کار نمیکنه
    ممنون میشم اگر میشه راهنمایی بفرمائین

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.