Home » Android » Android – How to change bottom navigation bar text's font family

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

Posted by: admin April 23, 2020 Leave a comment

Questions:

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!

How to&Answers:

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

Answer:

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>

Answer:

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"/>

Answer:

if you have a CustomFont in Asset Folder and you want to set in your bottom navigation use this code

  public class Font extends AppCompatActivity {
        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 Font Class in your MainActivity
Like This

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

Goodluck

Answer:

Per https://material.io/develop/android/components/bottom-navigation-view/, just set a fontFamily item for the TextAppearance.MaterialComponents.Caption style and it’ll Just Work. com.google.android.material.bottomnavigation.BottomNavigationView will use this by default.

Just know other components that rely on TextAppearance.MaterialComponents.Caption will get changed as well, but this might be desirable.

<style name="TextAppearance.MaterialComponents.Caption" parent="AppMaterialComponentsTheme">
        <item name="fontFamily">@font/example</item>
</style>

Answer:

public void setNavigationTypeface() {
        final Typeface avenirHeavy = Typeface.createFromAsset(this.getAssets(), "font2/Avenir-Heavy.ttf"); //replace it with your own font
        ViewGroup navigationGroup = (ViewGroup) bottomNavView.getChildAt(0);
        for (int i = 0; i < navigationGroup.getChildCount(); i++) {
            ViewGroup navUnit = (ViewGroup) navigationGroup.getChildAt(i);
            for (int j = 0; j < navUnit.getChildCount(); j++) {
                View navUnitChild = navUnit.getChildAt(j);
                if (navUnitChild instanceof BaselineLayout) {
                    BaselineLayout baselineLayout = (BaselineLayout) navUnitChild;
                    for (int k = 0; k < baselineLayout.getChildCount(); k++) {
                        View baselineChild = baselineLayout.getChildAt(k);
                        if (baselineChild instanceof TextView) {
                            TextView textView = (TextView) baselineChild;
                            textView.setTypeface(avenirHeavy);
                        }
                    }
                }
            }
        }
    }

Answer:

Kotlin Code of custom BottomNavigationView to set custom font:

1.Keep a font to assets directory of your android studio project. Here I used my font “SolaimanLipi_20-04-07.ttf”

2.Copy below kotlin code and paste to your android studio project.

class FontBottomNavigationView : BottomNavigationView {


constructor(context: Context) : super(context) {

}

constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {

}

constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {

}

private var fontFace: Typeface? = null

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
    super.onLayout(changed, left, top, right, bottom)

    val bottomMenu = getChildAt(0) as ViewGroup
    val bottomMenuChildCount: Int = bottomMenu.childCount
    var item: BottomNavigationItemView? = null
    var itemTitle: View? = null
    var shiftingMode: Field? = null

    if (fontFace == null){
        fontFace = Typeface.createFromAsset(context.assets, "SolaimanLipi_20-04-07.ttf") // font from assets directory
    }

    try {
        shiftingMode = bottomMenu.javaClass.getDeclaredField("mShiftingMode")
        shiftingMode.isAccessible = true
        shiftingMode.setBoolean(bottomMenu, false)
        shiftingMode.isAccessible = false
    } catch (e: Exception){
        e.printStackTrace()
    }

    for (i in 0..bottomMenuChildCount){
        try {
            item = bottomMenu.getChildAt(i) as BottomNavigationItemView
            itemTitle = item.getChildAt(1)
            ((itemTitle as BaselineLayout).getChildAt(0) as AppCompatTextView).typeface = fontFace
            ((itemTitle as BaselineLayout).getChildAt(1) as AppCompatTextView).typeface = fontFace
        } catch (e: Exception){
            e.printStackTrace()
        }

    }

}}

3.Use on xml file as like below:

<com.example.projectname.FontBottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/bottom_nav_menu" />

@Arash answer helped:

Answer:

If you want to change the text selection dynamically on selection, you can do bottomNav.itemTextAppearanceActive = R.style.yourstyle