Approach 1: Android O, using custom font resources
One of the new features in Android O is using Custom Font Resources.
Android O supports custom fonts via font resources. The magic lies in the app/res folder. Creating the font folder is easy. It is like every other resource like menu, values, drawable, etc.
These fonts are compiled in your R
file and are automatically available in Android Studio. You can access the font resources with the help of a new resource type, font. For example, to access a font resource, use @font/myfont
, or R.font.myfont
.
To use the Fonts in XML feature on devices running Android API version 14 and higher, use the Support Library 26.
dependencies { ... implementation 'com.android.support:design:26.1.0' ... }
So right click the res folder and create a new fonts folder.
Now you’re ready to drop in your fonts. So go ahead and pick a font of your choice. Android O supports both .otf (OpenType) and .ttf (TrueType) font formats.
Keep in mind, that resource files should use lowercase alphabets and underscores.
Head over to your XML layout file. Let’s skip the layout design and go straight to using our fonts.
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="@font/caffee_regular"/>
Here's simple TextView
. All you need to use a font is one attribute, and you’re good to go.
android:fontFamily="@font/caffee_regular"
You can assign a font programmatically too. First fetch the font Typeface. Then set it to your TextView
.
Typeface typeface = getResources().getFont(R.font.caffee_regular); tvTitle.setTypeface(typeface);
Additionally, you can specify a basic font style too. i.e. bold, italic or a combination of the two.
tvTitle.setTypeface(typeface, Typeface.BOLD_ITALIC);
You can also add custom fonts to any styles you’ve created in your app:
<style name="headlineFont" parent="@android:style/TextAppearance.Small"> <item name="android:fontFamily">@font/caffee_regular</item> </style>
Creating a Font Family. Sometimes you may unzip a font folder and discover multiple versions of the same font, such as an italicized version, or fonts with varying weights and thicknesses.
If you’re using multiple versions of the same font, then you may want to group them together into a font family. A font family is essentially a dedicated XML file where you define each version of the font, along with its associated style and weight attributes.
To create a font family:
Make sure you’ve added all the font files to your project’s res/font folder. Right-click your project's res/font folder, and then select New > Font resource file. Give this file a name, and then click OK. Open this XML file and define all the different versions of this font, along with their style and weight attributes, for example:
<?xml version="1.0" encoding="utf-8"?> <font-family xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <font android:font="@font/caffee_regular" android:fontStyle="normal" android:fontWeight="400" app:font="@font/caffee_regular" app:fontStyle="normal" app:fontWeight="400" /> <font android:font="@font/caffee_bold" android:fontStyle="normal" android:fontWeight="700" app:font="@font/caffee_bold" app:fontStyle="normal" app:fontWeight="700" /> <font android:font="@font/caffee_italic" android:fontStyle="italic" android:fontWeight="400" app:font="@font/caffee_italic" app:fontStyle="italic" app:fontWeight="400" /> <font android:font="@font/caffee_bold_italic" android:fontStyle="italic" android:fontWeight="700" app:font="@font/caffee_bold_italic" app:fontStyle="italic" app:fontWeight="700" /> </font-family>
You can then reference any of the fonts in this family using the android:fontFamily
attribute. For example:
android:fontFamily="@font/doublefeature_bold"
To retrieve fonts programmatically, call the ResourceCompat.getFont(Context, int)
method and provide an instance of Context
and the resource identifier.
Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
Approach 2: Typeface
In android, you can define your own custom fonts for the strings in your application. You just need to download (fonts.google.com) the required font from the internet, and then place it in assets/fonts folder.
After putting fonts in the assets folder under fonts folder, you can access it in your java code through Typeface
class. First, get the reference of the TextView
in the code. Its syntax is given below
TextView tvTitle = (TextView)findViewById(R.id.tvTitle);
The next thing you need to do is to call static method of Typeface
class createFromAsset()
to get your custom font from assets. Its syntax is given below
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/font_name.ttf");
The last thing you need to do is to set this custom font object to your TextView
Typeface
property. You need to call setTypeface()
method to do that. Its syntax is given below
tvTitle.setTypeface(tf);
So, let's create simple demo.
Create a new project and fill the required details.
Add a new folder named assets inside src/main/ folder so that we are going to have the src/main/assets directory. Then add a new folder named fonts inside src/main/assets folder. We are going to have the directory: src/main/assets/fonts and we are going to add a .ttf font file inside.
Open your activity_main.xml and create a simple TextView
.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:id="@+id/tvTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="70dip" android:layout_marginTop="30dip" android:text="Coffe + cake ?" /> </LinearLayout>
Now open your MainActivity
class file and try following code. In the following code I'm importing font from assets folder and using TypeFace
class for applying custom font on TextView
.
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Font path String fontPath = "fonts/coffee.ttf"; // Text view label TextView tvTitle = (TextView) findViewById(R.id.tvTitle); // Loading font face Typeface tf = Typeface.createFromAsset(getAssets(), fontPath); // Applying font tvTitle.setTypeface(tf); } }
Result
There is however one problem with this approach. Let's say you have font.ttf and font_bold.ttf. If your TextView
has the bold text style, it will be ignored because you applied the normal (non-bold) font. The same issue applies for italic styles. You can read solution here.
Approach 3: Calligraphy
We can use Calligraphy to set custom font for TextView
, Button
, EditText
from layout file.
First step is include the dependency to build.gradle.
dependencies { compile 'uk.co.chrisjenx:calligraphy:2.2.0' }
Add a new folder named assets inside src/main/ folder so that we are going to have the src/main/assets directory. Then add a new folder named fonts inside src/main/assets folder. We are going to have the directory: src/main/assets/fonts and we are going to add a .ttf font file inside.
Wrap the Activity
Context:
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); }
Last step is add TextView
, Button
, EditText
to layout file.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:ignore="MissingPrefix"> <TextView android:id="@+id/tvFont2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="30dip" android:layout_marginTop="20dip" android:text="TERMINATOR" fontPath="fonts/terminator.ttf"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Default font" android:layout_marginTop="30dip"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Custom font" fontPath="fonts/coffee.ttf"/> <EditText android:layout_marginTop="30dip" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Default font" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Default font" fontPath="fonts/coffee.ttf" /> </LinearLayout>
Result
Useful links