32

I am creating one Application in which I want to set custom font.

But I can't use custom Fonts in .xml file, for using this I need to initialize each and every TextView in .java file.

This process is Too much lengthy and time consuming.

If anyone know then please help me...

Ronak Selarka
  • 663
  • 1
  • 5
  • 13

8 Answers8

65

Android API 16+

Beginning with Android 8.0 (API 26), there is native support for setting the fonts in XML. However, using the support library extends this down to Android 4.1 (API 16).

enter image description here

1. Add a font to your project

  • Right click the res folder and go to New > Android Resource Directory. Type font as the name and font as the Resource type.
  • Copy and paste your font into the new res/font directory. I'm just using a single font in my example, the regular dancing script font. I renamed it to dancing_script.ttf just to avoid any potential naming problems with upper case or illegal characters.

2. Create a font-family XML file.

  • Right click the res/font folder and choose New > Font Resource File. Call it whatever you want. I'm calling mine my_custom_font.xml.
  • Paste in the following code. Note that the attributes are set twice, once for android (API 26+) and once for app (API 16+).

    <?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:fontStyle="normal"
            android:fontWeight="400"
            android:font="@font/dancing_script"
            app:fontStyle="normal"
            app:fontWeight="400"
            app:font="@font/dancing_script"
            />
    </font-family>
    

3. Set the font in XML

Now you can just use the fontFamily attribute to set the font in XML.

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:fontFamily="@font/my_custom_font" />

Notes

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 1
    Cause the older one was relevant at that point of time. Everyone should follow this answer as it's official recommendation by Android. But it doesn't mean that the previous answer or library like **Calligraphy** is of no use. They can be still be used in case where users are using below API level **16** which I think would be a rare scenario. – Abhishek Jan 22 '19 at 05:57
  • Is it even a good idea to mix your xml files with your ttf's? – 6rchid Nov 03 '19 at 09:53
  • @NocTurn, What I like about setting the font in xml is that it cleans up the code more. – Suragch Nov 03 '19 at 23:41
  • 1
    @Suragch It definitely does. I was using setTypeface this entire time until I came across your answer. Thanks for that :) – 6rchid Nov 04 '19 at 03:27
  • 1
    do the above steps given work for API below 26 (and above 16)? – NullByte08 Jun 04 '20 at 08:45
  • @NullByte08, They did at the time I wrote the answer and I expect they still do (though it would be AndroidX instead of the support library now). I use Flutter to develop Android apps now, so I haven't been keeping up with this. – Suragch Jun 04 '20 at 13:01
  • 1
    The process is much simpler in Android 2021.2.x Just create a folder "res/font/ and copy all font files there. Voila, you can now just use the fonts. The documentation is, however, outdate and is still showing what this post says. Beware, the folder type "font" is not available anymore. – tuxdost May 13 '22 at 21:32
  • @tuxdost, good to know. You might consider adding a new answer to this question with the details. Or you are welcome to edit this answer as well. I'm not updating my Android answers much anymore since I work on Flutter now. – Suragch May 14 '22 at 08:04
27

For your reference,

 public class MyTextView extends TextView {

    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyTextView(Context context) {
        super(context);
        init();
    }

    public void init() {
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/yourfont.ttf");
        setTypeface(tf ,1);

    }
}

In XML,

 <you_package.MyTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"       
        android:textSize="20sp"
        android:text="Your text"
        />
Srinivasan
  • 4,481
  • 3
  • 28
  • 36
  • @Srinivasan tried to use it in xml, but it throws `java.lang.NullPointerException` in `Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/yourfont.ttf");` even after putting my own font which is in asserts folder which works programmatically – Edijae Crusar Dec 21 '16 at 15:38
  • @gikarasojo kinene Can you please give me bit more information, like are you getting this exception within init() method or when you finding the MyTextView in onCreate(). And Keep in mind the font name and its extension is case sensitive. Don't forget to add your package name in XML – Srinivasan Dec 22 '16 at 05:26
  • @Srinivasan I was getting the exception in `init()` method on line `Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/RobotoCondensed-Regular.ttf");`. my font is `RobotoCondensed-Regular.ttf`. The error was being shown in xml preview and also when i run my app, it was also clashing. so i ended up using normal Textview(without extending it) and setting typeface this way ` `Typeface typeface = Typeface.createFromAsset(getContext().getAssets(),"fonts/RobotoCondensed-Regular.ttf"); textview.setTypeface(typeface);` ` – Edijae Crusar Dec 22 '16 at 09:57
  • I'm getting an error `Caused by: android.view.InflateException: Binary XML file line #35: Error inflating class com.app.etc.BaseActivity.MyTextView Caused by: java.lang.ClassNotFoundException: Didn't find class "com.app.etc.BaseActivity.MyTextView" on path: DexPathList[[zip file "/data/app/com.app.etc-1/base.apk"],nativeLibraryDirectories=[/data/app/com.app.etc-1/lib/arm64, /system/lib64, /vendor/lib64]]` – Jonny Wright Feb 04 '17 at 00:52
6

As per the documentation

Android 8.0 (API level 26) introduces a new feature, Fonts in XML, which lets you use fonts as resources. You can add the font file in the res/font/ folder to bundle fonts as resources. 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.

To add fonts as resources, perform the following steps in the Android Studio:

1.Right-click the res folder and go to New > Android resource directory. The New Resource Directory window appears.

2.In the Resource type list, select font, and then click OK. Note: The name of the resource directory must be font.

3.Add your font files in the font folder.

Creating a font family

A font family is a set of font files along with its style and weight details. In Android, you can create a new font family as an XML resource and access it as a single unit, instead of referencing each style and weight as separate resources. By doing this, the system can select the correct font based on the text style you are trying to use.

To create a font family, perform the following steps in the Android Studio:

1.Right-click the font folder and go to New > Font resource file. The New Resource File window appears.

2.Enter the file name, and then click OK. The new font resource XML opens in the editor.

3.Enclose each font file, style, and weight attribute in the element. The following XML illustrates adding font-related attributes in the font resource XML:

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>

Using fonts in XML layouts

In the layout XML file, set the fontFamily attribute to the font file you want to access.

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/lobster"/>

Open the Properties window to set the font for the TextView. Select a view to open the Properties window. Note: The Properties window is available only when the design editor is open. Select the Design tab at the bottom of the window.

Expand the textAppearance property, and then select the font from the fontFamily list.

Adding fonts to style

Open the styles.xml, and set the fontFamily attribute to the font file you want to access.

 <style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>
Android Developer
  • 9,157
  • 18
  • 82
  • 139
  • To use the Fonts in XML feature on devices running Android API version **16** and higher, use the Support Library 26. – Dr.jacky Apr 21 '18 at 08:40
5

As other answers suggest, you may use a font downloaded from google: Android Api 16+

open the textAppearance spinner in the designer: Choose a font for your View (Tap More Fonts...) like so:

enter image description here


In the dialog choose your custom font and download it to your project:
enter image description here

Now, you can refer to this font from xml using the fontFamily attribute:

    <Button
    android:id="@+id/btnTapMe"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/rounded_button"
    android:fontFamily="@font/aclonica"

    android:text="Tap Me!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

As a bonus, you can also use it from code: see snippet:

Toast toast = Toast.makeText(this, yourString, Toast.LENGTH_SHORT);
LinearLayout layout = (LinearLayout) toast.getView();
TextView tvToast = (TextView) layout.getChildAt(0);

//Here is the relevant part:
Typeface typeface = ResourcesCompat.getFont(this, R.font.aclonica);
tvToast.setTypeface(typeface);
toast.show();
TomerBu
  • 1,483
  • 15
  • 15
2

You can simply use custom Text view like

public class HelveticaRagularTextView extends TextView {

public HelveticaRagularTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(attrs);
}

public HelveticaRagularTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs);

}

public HelveticaRagularTextView(Context context) {
    super(context);
    init(null);
}

private void init(AttributeSet attrs) {
    // Just Change your font name
    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), getContext().getResources().getString(R.string.font_helvetica_regular));
    setTypeface(myTypeface);
}

}

Now you can HelveticaRagularTextView in your xml.

This is very easy to use

Harsh Patel
  • 657
  • 11
  • 26
0

Extend a custom class from TextView and customise font in the class. Then you would be able to use that custom textview class in you xml and you won't need to customize fonts dynamically in your code.

Good luck.

Mann
  • 560
  • 3
  • 13
0

Download a ttf file of the font you want to use and paste it in the

src->main->assets->font.ttf

Then for using ttf you need to do the following

for setting that font to particular text do following

   TextView tv_the = (TextView) findViewById(R.id.the);
    Typeface face = Typeface.createFromAsset(getAssets(), "font.ttf");
    tv_the.setTypeface(face);

If you want to set custom font to the whole activity do following

final ViewGroup mContainer = (ViewGroup) findViewById(android.R.id.content).getRootView();
        final Typeface mFont = Typeface.createFromAsset(getAssets(), "badoni2.ttf");
        Parameters.setAppFont(mContainer, mFont);

and add the Parameters class in your application

public class Parameters {

public static final void setAppFont(ViewGroup mContainer, Typeface mFont) {
    if (mContainer == null || mFont == null)
        return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children.
    for (int i = 0; i < mCount; ++i) {
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView) {
            // Set the font if it is a TextView.
            ((TextView) mChild).setTypeface(mFont);
        } else if (mChild instanceof ViewGroup) {
            // Recursively attempt another ViewGroup.
            setAppFont((ViewGroup) mChild, mFont);
        }

    }
}

Try this and let me know if it work for you

Rakshit Nawani
  • 2,604
  • 14
  • 27
0

Android 8.0 (API level 26) and Android Support Library 26 introduce support for APIs to request fonts from a provider application instead of bundling files into the APK or letting the APK download fonts. The feature is available on devices running Android API versions 14 and higher through the Support Library 26.

Please Follow this link https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts

rushab
  • 83
  • 1
  • 9