Material-components-android: Long text cutting off in BottomNavigationView

Created on 8 Jun 2018  路  34Comments  路  Source: material-components/material-components-android

Overview

Long texts cut off in BottomNavigationView only when tab is selected. When tab is unselected, it displays the text properly

When tab is unselected (Meine tickets)

screen shot 2018-06-08 at 08 45 31

When tab is selected (Meine tickets)

screen shot 2018-06-08 at 08 45 48

Reproduction steps

  • Setup bottom navigation view with 5 menu items with titles as: "Starseite", "Suchen", "Meine Tickets", "Verkaufen", "Profil"
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:id="@+id/action_home"
    android:icon="@drawable/tab_home_icon_selector"
    android:title="@string/nav_tab_home"/>

  <item
    android:id="@+id/action_explore"
    android:icon="@drawable/tab_explore_icon_selector"
    android:title="@string/nav_tab_explore"/>

  <item
    android:id="@+id/action_my_tickets"
    android:icon="@drawable/tab_tickets_icon_selector"
    android:title="@string/nav_tab_my_tickets"/>

  <item
    android:id="@+id/action_sell"
    android:icon="@drawable/tab_sell_icon_selector"
    android:title="@string/nav_tab_sell"/>

  <item
    android:id="@+id/action_profile"
    android:icon="@drawable/tab_profile_icon_selector"
    android:title="@string/nav_tab_profile"/>
</menu>
  • View style is:
<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/home.navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/home"/>

Version number

  • Found in version 1.0.0-alpha3

Operating system and device

  • Found in Nexus 5X emulator running Android Oreo

screen shot 2018-06-08 at 08 55 37

Most helpful comment

Use @sagrawal2418 answer:

BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationView.getChildAt(0);   
 for (int i = 0; i < menuView.getChildCount(); i++) {
        BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
        View activeLabel = item.findViewById(R.id.largeLabel);
        if (activeLabel instanceof TextView) {
            activeLabel.setPadding(0, 0, 0, 0);
        }
    }
}

in combination with @DhanalakshmiS answer, it works perfectly. There's no padding at all and text remains the same:

<!-- Bottom Menu Override -->
<dimen name="design_bottom_navigation_text_size" tools:override="true">12sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>

All 34 comments

Please add this property in your Xml
app:labelVisibilityMode="selected"

Not sure why this was closed.
I'm still having the issue with long labels being cut off when the labelVisibilityMode ="labeled".
Selected will only show label for the selected item, and I'm looking to show for all.

I am also facing this issue.

labelVisibilityMode ="labeled" should work too especially if active and inactive text size are the same.
It feels a bit strange that text get truncated just because the text color is changed.

Would you mind reconsidering reopening this issue?

Same goes for me. It would be nice to have this fixed... As @t7costa said i'm not sure why did they put an extra padding on the largeLabel...

As for now I use this for the active childView:

        BottomNavigationItemView itemView = (BottomNavigationItemView) childView;
        View activeLabel = itemView.findViewById(com.google.android.material.R.id.largeLabel);
        if (activeLabel != null && activeLabel instanceof TextView) {
            ((TextView)activeLabel).setPadding(0,0,0,0);
        }

But it is not the ideal, would be nice if we had an official API to influence this.
I do not see anything on the material design website about padding for active item, so it looks a deviation for me.

Would like this reopened as well. Facing the same issue and it doesn't seem to have a reason that it needs to work this way.

@kistitan How did you get the reference to the childView for the above solution?

This issue is being tracked at https://issuetracker.google.com/issues/115754572

Till Google Fixes this, I was able to to use @kistitan 's solution and also add this to the mix to help truncate the text properly in Kotlin:
activeLabel.ellipsize = TextUtils.TruncateAt.END

Also, we can override these dimens to change the text sizes of the labels in the active and inactive state.

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

Simply add these in your dimens.xml, so that the default text size will be overridden.

@kistitan and @kaustavjaiswal's solutions works like a chaaarm, thanks!

This problem still persists.
As @t7costa wrote: Problem's cause is active item textview's left and right padding.
@kistitan's solution works perfectly.
So another solution to this problem is overriding design_bottom_navigation_item.xml

Add design_bottom_navigation_item.xml from https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/bottomnavigation/res/layout/design_bottom_navigation_item.xml to your project's layout directory with name bottom_navigation_item.xml and delete left and right padding.
And then add this line to your project's any values resource file:
<item name="design_bottom_navigation_item" type="layout" tools:override="true">@layout/bottom_navigation_item</item>

This is being tracked in the Issue Tracker: https://issuetracker.google.com/115754572

public void removePaddingFromNavigationItem() {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationView.getChildAt(0);

    for (int i = 0; i < menuView.getChildCount(); i++) {
        BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
        View activeLabel = item.findViewById(R.id.largeLabel);
        if (activeLabel instanceof TextView) {
            activeLabel.setPadding(0, 0, 0, 0);
        }
    }
}

I used the global navigation view variable and then just call this method in the oncreate before the setOnNavigationItemSelectedListener

@sagrawal2418 works like a charm

Use @sagrawal2418 answer:

BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationView.getChildAt(0);   
 for (int i = 0; i < menuView.getChildCount(); i++) {
        BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
        View activeLabel = item.findViewById(R.id.largeLabel);
        if (activeLabel instanceof TextView) {
            activeLabel.setPadding(0, 0, 0, 0);
        }
    }
}

in combination with @DhanalakshmiS answer, it works perfectly. There's no padding at all and text remains the same:

<!-- Bottom Menu Override -->
<dimen name="design_bottom_navigation_text_size" tools:override="true">12sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>

Thanks, @FK1453, seems like the cleanest solution so far.

If you are using a theme within the BottomNavigationBar to set font family and text size, then overriding _design_bottom_navigation_text_size_ and _design_bottom_navigation_active_text_size_ won't work.
just to be clear ;)

Thanks for the Workaround. For those coming to here for the solution, it is working perfectly.

Thanks, @fatihkizmaz , works like a charm!=)

app:labelVisibilityMode="unlabeled"
this line of code on 'com.google.android.material.bottomnavigation.BottomNavigationView' work for me

@kistitan and @sagrawal2418 workaround adapted for kotlin:

val menuView = bottom_navigation_view.getChildAt(0) as? ViewGroup ?: return
menuView.forEachChild {
  it.findViewById<View>(R.id.largeLabel)?.setPadding(0, 0, 0, 0)
}

This is my approach: Just create a class that extends BottomNavigationView like this:

class PaddingLessBottomNavigation(context: Context, attrs: AttributeSet) :
BottomNavigationView(context, attrs) {

override fun onFinishInflate() {
    super.onFinishInflate()
    val menuView = getChildAt(0) as? ViewGroup
    menuView?.let {
        for (child in 0 until it.childCount) {
            val menuItem = it.getChildAt(child)
            val largeLabel =
                menuItem?.findViewById<View>(com.google.android.material.R.id.largeLabel)
            largeLabel?.setPadding(0, 0, 0, 0)
        }
    }
}

}

After that you just have to use your class on you layout like you do on normal BottomNavigationView:

android:id="@+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="@color/bottom_navigation_background"
android:theme="@style/BottomNavigation"
app:elevation="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:labelVisibilityMode="labeled"
app:menu="@menu/menu_bottom_navigation"
/>

Upgrading to com.google.android.material:material:1.1.0-beta01 will fix this issue.

@layout/bottom_navigation_item

Perfect!

bottomNavigation Icon by default is showing black-color.How resoved the icon issue in bottomNavigationView android?

Upgrading to com.google.android.material:material:1.1.0 will fix long text cutting off bug.

In this theme => Theme.MaterialComponents.Light.NoActionBar.

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

does not worked for me.
What I did to resolve is

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

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

Define these in styles and used in the XML like below.

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    ...........
    app:itemTextAppearanceActive="@style/BottomNavigationView.Active"
    app:itemTextAppearanceInactive="@style/BottomNavigationView.InActive"
    .......
    android:theme="@style/BottomNavigationTheme"
    />

Hope its helpful to someone.

@paulshandomain @Dimas Mendes its work. thank you

Reset BottomNavigationItemView long click listener, can resolve long text cutting off in BottomNavigationView. e.g:
BottomNavigationItemView[] views = dataBinding.bottomNav.getBottomNavigationItemViews();
for (BottomNavigationItemView v : views) {
if (v != null) {
v.setOnLongClickListener(v1 -> true);
}
}

This problem still persists.
As @t7costa wrote: Problem's cause is active item textview's left and right padding.
@kistitan's solution works perfectly.
So another solution to this problem is overriding design_bottom_navigation_item.xml

Add design_bottom_navigation_item.xml from https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/bottomnavigation/res/layout/design_bottom_navigation_item.xml to your project's layout directory with name bottom_navigation_item.xml and delete left and right padding.
And then add this line to your project's any values resource file:
<item name="design_bottom_navigation_item" type="layout" tools:override="true">@layout/bottom_navigation_item</item>

I used this solution with AutoSizing. This works absolutely fine for me.

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_marginTop="@dimen/_8dp"
        android:layout_marginBottom="@dimen/_8dp"
        android:layout_gravity="center_horizontal"
        android:contentDescription="@null"
        android:duplicateParentState="true"/>
    <com.google.android.material.internal.BaselineLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:paddingBottom="10dp"
        android:clipToPadding="false"
        android:duplicateParentState="true">
        <TextView
            android:id="@+id/smallLabel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dimen_12_dp"
            android:layout_marginRight="@dimen/dimen_12_dp"
            android:duplicateParentState="true"
            app:autoSizeTextType="uniform"
            app:autoSizeMinTextSize="8sp"
            app:autoSizeMaxTextSize="12sp"
            app:autoSizeStepGranularity="1sp"
            android:ellipsize="end"
            android:maxLines="1"/>
        <TextView
            android:id="@+id/largeLabel"
            android:layout_width="match_parent"
            android:layout_marginLeft="@dimen/_8dp"
            android:layout_marginRight="@dimen/_8dp"
            android:layout_height="wrap_content"
            android:paddingLeft="0dp"
            android:paddingRight="0dp"
            android:duplicateParentState="true"
            android:maxLines="1"
            app:autoSizeTextType="uniform"
            app:autoSizeMinTextSize="10sp"
            app:autoSizeMaxTextSize="16sp"
            app:autoSizeStepGranularity="1sp"
            android:ellipsize="end"
            android:visibility="invisible"/>
    </com.google.android.material.internal.BaselineLayout>
</merge>

It's fixed now all what you need is to upgrade the version as the following
implementation 'com.google.android.material:material:1.1.0'

Issue still reproducable in implementation 'com.google.android.material:material:1.2.1'

Having the same issue with '1.3.0-alpha03'.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahmaducg picture ahmaducg  路  3Comments

JavierSegoviaCordoba picture JavierSegoviaCordoba  路  3Comments

gabrielemariotti picture gabrielemariotti  路  3Comments

magnusfernandes picture magnusfernandes  路  3Comments

gabrielemariotti picture gabrielemariotti  路  3Comments