How to change navigation drawer font?
Asked Answered
E

7

31

I want to use my own font for navigation drawer in android.I use the library comes with android studio according to this answer: https://mcmap.net/q/271442/-how-to-create-a-custom-navigation-drawer-in-android. But I don't know how to change the font and make it RTL. I searched a lot and I found how to make the drawer RTL. I use this code:

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

and Android - Is Navigation Drawer from right hand side possible?

But as you know this only works in API 17 and above. Please help! How to change the menu font? How to make the layout RTL in right way?!

Edited: My font "TTF" file is in assets/fonts and I know how to set it for a textview using java, but I don't know how to set it to navigation drawer menu.

Ethic answered 5/1, 2016 at 12:22 Comment(2)
did you use a custom xml row for managing menu.. then i could tell you how do you change your menu text fontInfanta
@Tanimreja Yes, I did!Ethic
E
40

I found the answer: First create this class in your project:

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {

    private final Typeface newType;

    public CustomTypefaceSpan(String family, Typeface type) {
        super(family);
        newType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, newType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

Then add this method to your activity you want to change the font of navigation drawer menu:

private void applyFontToMenuItem(MenuItem mi) {
        Typeface font = Typeface.createFromAsset(getAssets(), "ds_digi_b.TTF");
        SpannableString mNewTitle = new SpannableString(mi.getTitle());
        mNewTitle.setSpan(new CustomTypefaceSpan("" , font), 0 , mNewTitle.length(),  Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        mi.setTitle(mNewTitle);
}

and then add call the method you just added in your activity:

navView = (NavigationView) findViewById(R.id.navView);
Menu m = navView.getMenu();
for (int i=0;i<m.size();i++) {
    MenuItem mi = m.getItem(i);

    //for aapplying a font to subMenu ...
    SubMenu subMenu = mi.getSubMenu();
    if (subMenu!=null && subMenu.size() >0 ) {
        for (int j=0; j <subMenu.size();j++) {
            MenuItem subMenuItem = subMenu.getItem(j);
            applyFontToMenuItem(subMenuItem);
        }
    }

    //the method we have create in activity
    applyFontToMenuItem(mi);
}
Ethic answered 9/1, 2016 at 7:10 Comment(4)
excellent. but how to change the direction from left to right. i mean set it as RTL . but for all APIs not only for 17 and above?Copra
@HosseinMansouri this case you have to add drawer in your project manually and not using the google navigation drawer library.Ethic
any sample of drawer ?Copra
@HosseinMansouri Of course it's available, google it. :))Ethic
M
70

You can do this in more easy way.

First go in style.xml and create there a new style.

 <style name="RobotoTextViewStyle" parent="android:Widget.TextView">
      <item name="android:fontFamily">@font/sans-serif-smallcaps</item>
 </style>

and the second is go to your navigation xml code and put the item text appearance there.

app:itemTextAppearance="@style/RobotoTextViewStyle"

now your final navigation code should be this.

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:itemTextAppearance="@style/RobotoTextViewStyle"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_home"
        app:menu="@menu/activity_home_drawer" />
Myocardium answered 15/11, 2018 at 0:7 Comment(3)
wish i'd upvote twice, this shouldn't be a code solution... but xmlHelen
Sir, you are a legend. Thanks a million for this answerSuzisuzie
Yes, you deserve twice upvote.Adigranth
E
40

I found the answer: First create this class in your project:

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {

    private final Typeface newType;

    public CustomTypefaceSpan(String family, Typeface type) {
        super(family);
        newType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, newType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

Then add this method to your activity you want to change the font of navigation drawer menu:

private void applyFontToMenuItem(MenuItem mi) {
        Typeface font = Typeface.createFromAsset(getAssets(), "ds_digi_b.TTF");
        SpannableString mNewTitle = new SpannableString(mi.getTitle());
        mNewTitle.setSpan(new CustomTypefaceSpan("" , font), 0 , mNewTitle.length(),  Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        mi.setTitle(mNewTitle);
}

and then add call the method you just added in your activity:

navView = (NavigationView) findViewById(R.id.navView);
Menu m = navView.getMenu();
for (int i=0;i<m.size();i++) {
    MenuItem mi = m.getItem(i);

    //for aapplying a font to subMenu ...
    SubMenu subMenu = mi.getSubMenu();
    if (subMenu!=null && subMenu.size() >0 ) {
        for (int j=0; j <subMenu.size();j++) {
            MenuItem subMenuItem = subMenu.getItem(j);
            applyFontToMenuItem(subMenuItem);
        }
    }

    //the method we have create in activity
    applyFontToMenuItem(mi);
}
Ethic answered 9/1, 2016 at 7:10 Comment(4)
excellent. but how to change the direction from left to right. i mean set it as RTL . but for all APIs not only for 17 and above?Copra
@HosseinMansouri this case you have to add drawer in your project manually and not using the google navigation drawer library.Ethic
any sample of drawer ?Copra
@HosseinMansouri Of course it's available, google it. :))Ethic
S
14

Step 1:Make Style as follows in style.xml

<style name="NavigationView" >
<item name="fontFamily">@font/helvetica_neue_light</item>
</style>

Step 2: Add style as theme in your android.support.design.widget.NavigationView

android:theme="@style/NavigationView"

Stowe answered 18/10, 2018 at 5:53 Comment(3)
Thank you it work very good and simple without create any other class !!!!!Vedanta
there's no parent style to inherit from ?Cecilececiley
UPDATE: nope, no parent style needed. Weird how Android is inconsistent in this regard.Cecilececiley
R
10

Adding to rischan's answer.

I edited 'mi' directly as those are my drawer menu titles. Then I changed the s.setSpan 1st parameter to use a custom class CustomTypefaceSpan.

    // Navigation View
    NavigationView navigationView = (NavigationView) 
    findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    Menu m = navigationView .getMenu();

    Typeface tf1 = Typeface.createFromAsset(getAssets(), "font/Gotham Narrow Extra Light.otf");

    for (int i=0;i<m.size();i++) {

        MenuItem mi = m.getItem(i);

        SpannableString s = new SpannableString(mi.getTitle());
        s.setSpan(new CustomTypefaceSpan("", tf1), 0, s.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        mi.setTitle(s);

    }

CustomTypefaceSpan Class:

package my.app;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {

    private final Typeface newType;

    public CustomTypefaceSpan(String family, Typeface type) {
        super(family);
        newType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, newType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

Can't believe how complicated it is just to change the fonts for the menu.

Roark answered 12/10, 2017 at 20:5 Comment(1)
+1 for custom font effort and add font for sub menu too.so that it would be clear cut answer for total navigation menu.Idolatrous
G
7

Thank you! I've successfully changed font on navigation drawer based on @Amir H post but with configuration (just add this several lines into your activity)

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        Menu m = navigationView .getMenu();

        for (int i=0;i<m.size();i++) {
            MenuItem mi = m.getItem(i);

            //for applying a font to subMenu ...
            SubMenu subMenu = mi.getSubMenu();
            if (subMenu!=null && subMenu.size() >0 ) {
                for (int j=0; j <subMenu.size();j++) {
                    MenuItem subMenuItem = subMenu.getItem(j);
                    SpannableString s = new SpannableString(subMenuItem.getTitle());
                    s.setSpan(new TypefaceSpan("fonts/yourfontname.ttf"), 0, s.length(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    subMenuItem.setTitle(s);
                }
            }

        }

Maybe it will help someone :)

Grecize answered 21/4, 2016 at 8:55 Comment(0)
D
4

It Works For Fonts Only

  1. First Of All Add color of your font (if you want to change) in colors.xml file located at res->values->colors.xml like

    <color name="black">#000000</color> // it's for black don't go for white color
    
  2. Then edit style.xml file located at same values directory (there are two files edit that file which having your theme with style name="your_theme" or find line in that two file

  3. Here we have to set font property. So you have to create new style tag in enclosing resource tags. in my case I create

    <style name="MyText" parent="@android:style/TextAppearance.Medium">
        <item name="android:textSize">20sp</item> //size of font
        <item name="android:textColor">@color/black</item> //color of font
        <item name="android:typeface">sans</item> // type how it appear
    </style>
    

    Note that Name given for this tag is MyText. Now we have to use this name in aboved first style block whose name is your appication theme.

  4. Mentioned this new style in above appication theme style tag. In my case its like

    <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="android:textViewStyle">@style/MyText</item> //MyText its custom style for font
        </style>
    
Diphtheria answered 5/1, 2016 at 12:53 Comment(1)
@Abishek It didn't change the font. It's only changed the size and color.And of course no change in navigation drawer!!!! Furthermore my font file is in assets/fonts folder.Ethic
B
1

first, create an XML file in under res>>values with a name style.xml

then copy and add this code under <resource><style name="mynavigationfont" > <item name="fontFamily">@font/sans-serif</item> </style> </resource>

Note: - add this code in <resource ...here.. if >

<?xml version="1.0" encoding="UTF-8"?>

if you do not add this then it may show error

finally, add this to your XML

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:itemTextAppearance="@style/RobotoTextViewStyle"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_home"
    app:menu="@menu/activity_home_drawer" />

this line - app:itemTextAppearance="@style/mynavigationfont"

Berenice answered 24/12, 2022 at 5:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.