73

I am trying to change the textSize of BottomNavigationView from android support library 25.0.0

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_navigation_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/colorPrimaryDark"
        android:foregroundTint="@color/colorAccent"
        app:itemIconTint="@android:color/white"
        app:itemTextColor="@android:color/white"
        app:layout_anchor="@id/lyt_container"
        app:layout_anchorGravity="bottom"
        app:itemTextAppearance="@style/TextStyleBNV"
        app:menu="@menu/nav_menu" />

<style name="TextStyleBNV">
        <item name="android:textSize">@dimen/twelve_sp</item>
        <item name="android:padding">0dp</item>
        <item name="textAllCaps">false</item>
    </style>

Is there anything i am missing.

silentsudo
  • 6,730
  • 6
  • 39
  • 81

8 Answers8

174

Unfortunately this first version of BottomNavigationView came with a lot of limitations. And for now you can't change titles size just using the support design API. So to solve this limitation while google doesn't implement it, you can do:

In your dimen.xml you can put:

    <dimen name="design_bottom_navigation_text_size" tools:override="true">30sp</dimen>
    <dimen name="design_bottom_navigation_active_text_size" tools:override="true">30sp</dimen>

Doing this you are overriding the default value of dimen that the internal classes of BottomNavigationView use. So be carreful.

Sanf0rd
  • 3,644
  • 2
  • 20
  • 29
  • 2
    @Sanf0rd I want to do something like this for other attributes, but don't know where to search for the names to add style override. Can you point me where to look? // Side note: I want to change the side padding of the selected BottomNavigation item when 5 items are in the menu. It looks waaay larger than it's shown on the guidelines, weird way of implementing an "official" solution.. – quezak Nov 18 '16 at 18:13
  • 1
    I Just searched inside the internal classes and layout files of the bottomNavigation. – Sanf0rd Nov 20 '16 at 15:42
  • 3
    Also if invalid you have to add namespase in that dimens.xml . Like .... – CodeToLife May 31 '17 at 05:36
  • 1
    how to set font to title and SingleLine= false ? – andro Jan 15 '18 at 09:26
  • @Sanf0rd you saved my Time. +1 vote for u. Thank you – Sagar Aghara Feb 07 '18 at 06:28
  • Actually this solution helps you to avoid the "animation" of increasing the text size when selecting one of the elements, so that the behaviour is similar to the Youtube bottom navigation bar. This hack works also for support 28.0.0 – Sca09 Dec 17 '18 at 15:30
  • It still works nicely with the latest stable androidx version. – Nantoka Apr 01 '19 at 19:43
  • 13
    it doesn't work in androidx com.google.android.material.bottomnavigation.BottomNavigationView – denizs May 15 '19 at 15:50
  • Thank you so much for the solution, it saved much of my time! – hetsgandhi Nov 15 '19 at 05:57
  • if someone is looking for all other dimensions that can be overridden: https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/bottomnavigation/res/values/dimens.xml – Domenico Aug 03 '21 at 10:55
  • I get the error "Namespace 'tools' is not bound " – VanessaF Aug 26 '22 at 16:11
  • @VanessaF add xmlns:tools="http://schemas.android.com/tools" to resources tag – Squareoot Nov 02 '22 at 19:48
99

You can change BottomNavigationView text appearance by defining your own styles for Component Attributes itemTextAppearanceActive and itemTextAppearanceInactive. By default they have textAppearanceCaption check section Theme Attribute Mapping in the docs Bottom Navigation.

<android.support.design.widget.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:itemTextAppearanceActive="@style/BottomNavigationView.Active"
    app:itemTextAppearanceInactive="@style/BottomNavigationView"
    app:menu="@menu/bottom_navigation_main" />

styles.xml

<style name="BottomNavigationView" parent="@style/TextAppearance.AppCompat.Caption">
    <item name="android:textSize">10sp</item>
</style>

<style name="BottomNavigationView.Active" parent="@style/TextAppearance.AppCompat.Caption">
    <item name="android:textSize">11sp</item>
</style>
  • Next, Change Text Color selected and icon:
    Just Create bottom_nav_icon_color_selector & bottom_nav_text_color_selector on drawable to edit default value.

  • For change icon color - bottom_nav_icon_color_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorIcon Active -->
    <item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorIcon Active -->
    <item android:color="@color/colorIconInActive" /> <!-- colorIcon InActive -->
</selector>
  • For change text color - bottom_nav_text_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorText Active -->
    <item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorText Active -->
    <item android:color="@color/colorTextInActive" /> <!-- colorText InActive -->
</selector>
  • Note : @color/colorIconInActive is a color disable/inactive, you can set this color in your res-values-colors
  • Finish, try to see, your navigation bottom. color icon and text will be change.
rivaldy
  • 137
  • 3
  • 7
Volodymyr
  • 6,393
  • 4
  • 53
  • 84
  • 1
    Works, but it also resets various properties, such as the color of the text. Is it possible to change just the text size? – android developer Dec 25 '18 at 15:21
  • @androiddeveloper you can set your app theme as a parent and it will pick colors from your app theme. – Volodymyr Jan 03 '19 at 16:19
  • 1
    Parent of what? You mean the Activity theme? Please explain. – android developer Jan 06 '19 at 12:33
  • 1
    Note that you don't need to create 2 different styles. Just apply the same one twice. – Albert Vila Calvo Aug 08 '19 at 12:15
  • 1
    I used the accepted answer with the AppCompat theme and that worked, but due to using Chips Group I need to shift to the Material Component theme and it not worked anymore. Your Text method helped in that case for setting style to text instead of using overridden dimens. Thanks a Lot +1. – MRamzan Apr 20 '20 at 18:24
17

I used the snippet below to change the NavigationView style using the Material design.

<style name="MyBottomNavigationView" parent="Widget.MaterialComponents.BottomNavigationView">
    <item name="itemIconTint">@color/bottom_navigation_item_selector</item>
    <item name="itemTextColor">@color/bottom_navigation_item_selector</item>
    <item name="itemTextAppearanceActive">@style/MyBottomNavigationView.TextAppearance</item>
    <item name="itemTextAppearanceInactive">@style/MyBottomNavigationView.TextAppearance</item>
</style>

<style name="MyBottomNavigationView.TextAppearance" parent="TextAppearance.MaterialComponents.Caption">
    <item name="android:textSize">11sp</item>
    <item name="fontFamily">@font/exo2_medium</item>
</style>

Then set the style to the BottomNavigationView element

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    style="@style/MyBottomNavigationView" />
Pedro Romão
  • 2,285
  • 28
  • 22
16

you can change it like this. you have to only khow the id of labels that google support used

BottomNavigationView bottomNavigationView = (BottomNavigationView) fragmentActivity.findViewById(R.id.bottom_navigation);
    TextView textView = (TextView) bottomNavigationView.findViewById(R.id.menu_item_home).findViewById(R.id.largeLabel);
    textView.setTextSize(8);

LargeLabel is the id of label that google used in its library

BoshRa
  • 778
  • 1
  • 8
  • 15
2

Another solution is to use Spannable to adjust the size color, font or other a text attributes ....

private static class MenuSpannable extends MetricAffectingSpan{
        int color = Color.RED;
        int size = 40;

        public MenuSpannable() {
            setSelected(false);
        }

        @Override
        public void updateMeasureState(TextPaint p) {
            p.setColor(color);
            p.setTextSize(size);
            /* p.setText --- whatever --- */
        }

        @Override
        public void updateDrawState(TextPaint tp) {
            tp.setColor(color);
            tp.setTextSize(size);
            /* tp.setText --- whatever --- */
        }
        private void setSelected(boolean selected){
            if(selected){
                color = Color.RED;
                size = 40;
            }else{
                color = Color.BLUE;
                size = 20;
            }
        }
}

And then set the span for any menu item...

@Override
protected void onCreate(Bundle savedInstanceState) {
        BottomNavigationView mBottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_menu);
        final Menu menu = mBottomNavigationView.getMenu();
        final Font font = Font.getFromContext(this);
        for(int i = 0; i < menu.size(); i++) {
            SpannableString spannableString = new SpannableString(menu.getItem(i).getTitle());
            spannableString.setSpan(new MenuSpannable(),0,spannableString.length(),0);
            menu.getItem(i).setTitle(spannableString);
        }
}

In case you want the text to change with the selection state

mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
             Menu menu = mBottomNavigationView.getMenu();
             for(int i = 0; i < menu.size(); i++) {
                MenuSpannable menuSpannable = new MenuSpannable();
                menuSpannable.setSelected(item.getItemId() == menu.getItem(i).getItemId());
                SpannableString sString = new SpannableString(menu.getItem(i).getTitle());
                sString.setSpan(menuSpannable,0,sString.length(),0);
                menu.getItem(i).setTitle(sString);
                }
            return false;
            }
        });
Yan
  • 1,569
  • 18
  • 22
1

To do this, I just decided to override the navigation item layout :

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="@dimen/design_bottom_navigation_margin"
        android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
        android:duplicateParentState="true" />
    <android.support.design.internal.BaselineLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:clipToPadding="false"
        android:paddingBottom="10dp"
        android:duplicateParentState="true">
        <TextView
            android:id="@+id/smallLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/design_bottom_navigation_text_size"
            android:singleLine="true"
            android:duplicateParentState="true" />
        <TextView
            android:id="@+id/largeLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="invisible"
            android:textSize="@dimen/design_bottom_navigation_active_text_size"
            android:singleLine="true"
            android:duplicateParentState="true" />
    </android.support.design.internal.BaselineLayout>
</merge>

Just make sure you name it design_bottom_navigation_item

Pafoid
  • 435
  • 4
  • 8
-1

Add the TabTextStyle code inside the UpdateBarTextColor (this void exist in BottomBarPageRenderer)

 void UpdateBarTextColor()
    {
        if (_disposed || _bottomBar == null)
        {
            return;
        }
        //This is linked to styles.xml to set size of text
        _bottomBar.SetTextAppearance(Resource.Style.TabTextStyle);
        //Set color of text and icon in BottomNavBar
        _bottomBar.SetActiveTabColor(Element.BarTextColor.ToAndroid(Color.FromHex("#0094F0")));
        // The problem SetActiveTabColor does only work in fiexed mode // haven't found yet how to set text color for tab items on_bottomBar, doesn't seem to have a direct way
    }

And then add this inside the styles.xml:

<style name="TabTextStyle" parent="@android:style/TextAppearance.Medium"> 
    <item name="android:textSize">8dp</item> 
</style> 
petterandersson
  • 71
  • 2
  • 10
-5

Unfortunately overriding dimen did not work for me at com.android.support:design:28.0.0

Finally I was able to change the text size by using <font size="8"></font> tag for each title string resource used in menu.xml.

For example I have a menu declared here menu_bottom_navigation.xml, which has item like:

<item
  ...
  android:title="@string/main_navi_item_home"
  .../>

In string.xml, set the target resource like:

<string name="main_navi_item_home"><font size="8">Home</font></string>
KinoP
  • 1,532
  • 15
  • 23
  • What is the "8" ? Is it in dp, in sp... ? – android developer Dec 25 '18 at 15:17
  • Nope, didn't work for me with the font tag in the string declaration. java.lang.RuntimeException: Unable to start activity ComponentInfo{ca.ami.android.amiandroid/ca.ami.android.amiandroid.activities.MainActivityTV}: android.view.InflateException: Binary XML file line #28: Binary XML file line #28: Error inflating class android.support.design.widget.BottomNavigationView – Kornilov Ruslan Sep 01 '19 at 15:29
  • Don't use this method. It somehow worked for my rare case. – KinoP Feb 12 '21 at 08:34