Android - How to change bottom navigation bar text's font family

35,925

Solution 1

add the font file in the res/font/ folder to bundle fonts as resources

then

You can change it using style resources. In your styles.xml:

<style name="Widget.BottomNavigationView" 
    parent="Widget.Design.BottomNavigationView">
    <item name="fontFamily">@font/your_font</item>
</style>

Then apply it as a theme in your view:

<android.support.design.widget.BottomNavigationView
    ...
    android:theme="@style/Widget.BottomNavigationView"
/>

Just checked on my app, it works fine.

reference: https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html#fonts-in-code

Solution 2

In your layout:

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:itemTextAppearanceActive="@style/BottomNavigationViewTextStyle"
    app:itemTextAppearanceInactive="@style/BottomNavigationViewTextStyle"
    ... />

In your styles.xml:

<style name="BottomNavigationViewTextStyle">
    ...
    <item name="android:fontFamily">@font/whatever_font</item>
    ...
</style>

Solution 3

If you have a CustomFont in "Asset Folder" and you want to set in your "Bottom Navigation" use this code

        public static void persian_iran_font(final Context context, final View v) {
            try {
                if (v instanceof ViewGroup) {
                    ViewGroup vg = (ViewGroup) v;
                    for (int i = 0; i < vg.getChildCount(); i++) {
                        View child = vg.getChildAt(i);
                        persian_iran_font(context, child);
                    }
                } else if (v instanceof TextView) {
                    ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "teshrinarmedium.otf"));
                }
            } catch (Exception e) {
            }
        }
    

And then use methode in your MainActivity Like This

  BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
  persian_iran_font(getApplicationContext(), navigation);

kotlin Version

fun persian_iran_font(context: Context, v: View) {
    try {
        if (v is ViewGroup) {
            val vg = v as ViewGroup
            for (i in 0 until vg.childCount) {
                val child: View = vg.getChildAt(i)
                persian_iran_font(context, child)
            }
        } else if (v is TextView) {
            (v as TextView).setTypeface(
                Typeface.createFromAsset(
                    context.getAssets(),
                    "teshrinarmedium.otf"
                )
            )
        }
    } catch (e: Exception) {
    }
}

Goodluck

Solution 4

This can be done by overriding onLayout method of BottomNavigationView class then using the extended tag. This approach also shows all menu titles and disables shifting.

public final class ExtendedBottomNavigationView extends BottomNavigationView{
    private final Context context;
    private Typeface fontFace = null;

    public ExtendedBottomNavigationView(Context context, AttributeSet attrs){
        super(context, attrs);
        this.context = context;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom){
        super.onLayout(changed, left, top, right, bottom);
        final ViewGroup bottomMenu = (ViewGroup)getChildAt(0);
        final int bottomMenuChildCount = bottomMenu.getChildCount();
        BottomNavigationItemView item;
        View itemTitle;
        Field shiftingMode;

        if(fontFace == null){
            fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.VazirBold));
        }
        try {
            //if you want to disable shiftingMode:
            //shiftingMode is a private member variable so you have to get access to it like this:
            shiftingMode = bottomMenu.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(bottomMenu, false);
            shiftingMode.setAccessible(false);
        } catch (NoSuchFieldException e){
            e.printStackTrace();
        } catch (IllegalAccessException e){e.printStackTrace();}

        for(int i=0; i<bottomMenuChildCount; i++){
            item = (BottomNavigationItemView)bottomMenu.getChildAt(i);
            //this shows all titles of items
            item.setChecked(true);
            //every BottomNavigationItemView has two children, first is an itemIcon and second is an itemTitle
            itemTitle = item.getChildAt(1);
            //every itemTitle has two children, first is a smallLabel and second is a largeLabel. these two are type of AppCompatTextView
            ((TextView)((BaselineLayout) itemTitle).getChildAt(0)).setTypeface(fontFace, Typeface.BOLD);
            ((TextView)((BaselineLayout) itemTitle).getChildAt(1)).setTypeface(fontFace, Typeface.BOLD);
        }
    }
}

Then use it like this:

<your.package.name.ExtendedBottomNavigationView android:id="@id/bottomMenu" style="@style/bottomMenu"/>

Solution 5

For Kotlin Lover

Create an extension class for custom asset font

    /**
      * Method for Bottom Navigation Font Family
      *@param view
      *
      * */
private fun navigationTextFont(view: View) {
    if (view is ViewGroup) {
        for (i in 0 until view.childCount) {
            val child = view.getChildAt(i)
            navigationTextFont(child)
        }
    } else if (view is TextView) {
        // font from asset
        view.typeface = Typeface.createFromAsset(this.assets, "fonts/roboto_bold.ttf")
        
        // Or Font From resource
        view.typeface = ResourcesCompat.getFont(this,R.font.roboto_bold)
    }
}

Now call this extension

   navigationTextFont(yourNavigationViewId)

Good Luck

Share:
35,925
Neha Beniwal
Author by

Neha Beniwal

Updated on January 25, 2022

Comments

  • Neha Beniwal
    Neha Beniwal over 2 years

    I have created a bottom bar navigation in my android page. But now I want to apply the custom font-family in bottom navigation texts.

    This is the bottom navigation code in .xml file:

    <android.support.design.widget.BottomNavigationView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/bottomNavView_Bar"
                android:background="@drawable/white_grey_border_top"
                app:menu="@menu/bottom_navigation_menu">
    </android.support.design.widget.BottomNavigationView>
    

    Also, code in bottom_navigation_menu.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          >
    
        <item
            android:id="@+id/ic_newsfeed"
            android:icon="@drawable/ic_menu_camera"
            android:title="NEWSFEED"
            />
    
            <item
                android:id="@+id/ic_explorer"
                android:icon="@drawable/ic_home_black_24dp"
                android:title="EXPLORER"
                />
            <item
                android:id="@+id/ic_notify"
                android:icon="@drawable/ic_notifications_black_24dp"
                android:title="NOTIFY"
                />
            <item
                android:id="@+id/ic_more"
                android:icon="@drawable/ic_dashboard_black_24dp"
                android:title="MORE"
                />
    
    </menu>
    

    Help would be appreciated.

    Thanks in advance!

  • Varad Mondkar
    Varad Mondkar over 5 years
    Thanks. This answer should be marked as accepted. In my case, I am using Calligraphy library so my style xml was like <item name="fontPath">fonts/lato_medium.ttf</item>
  • Amin Keshavarzian
    Amin Keshavarzian about 5 years
    this is better than A. Kazarovets's answer because it doesn't override and screw with animation
  • hassan moradnezhad
    hassan moradnezhad over 4 years
    why did you extends Font class from AppCompatActivity?
  • Kieron
    Kieron over 4 years
    FYI: This didn't work for me with android:fontFamily, only with just fontFamily (the equivalent of app:fontFamily)
  • MohammadReza
    MohammadReza over 4 years
    @hassanmoradnezhad we needed context and view so had to extends from AppCompatActivity
  • Ali Al Fayed
    Ali Al Fayed over 3 years
    Good Answer it is working with Theme.MaterialComponents style
  • A.Mamode
    A.Mamode over 3 years
    Be aware that if you want to change your text's font you have to specify : name="fontFamily" and NOT name="android:fontFamily"
  • Gianluca Veschi
    Gianluca Veschi over 2 years
    This answer works but it also overrides the default animation