Search code examples
androidbottomnavigationviewmaterial-components-android

BottomNavigationView - why is there not enough space for the badge Drawable?


I use a BottomNavigationView from the material library: const val material = "com.google.android.material:material:1.4.0-rc01"

and set/update a badge on it using the following binding:

@BindingAdapter("cartCount")
fun BottomNavigationView.updateCartCount(count: Int) {
    getOrCreateBadge(R.id.action_cart).apply {
        isVisible = count > 0
        if (isVisible) number = count
    }
}

Here's the View in XML (inside a ConstraintLayout)

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        cartCount="@{viewModel.cartCount}"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@color/white"
        app:elevation="8dp"
        app:itemIconTint="@color/bottom_nav_item_color"
        app:itemTextColor="@color/bottom_nav_item_color"
        app:labelVisibilityMode="labeled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/menu_bottom_nav" />

My issue is that there seems to be not enough space for the badge:

cart unselected

Which is more noticeable when the item is selected:

cart selected

What I have tried to fix the issue, to no avail:

  • using a different material version, trying different versions (starting with 1.3.0)
  • increasing the height of the BottomNavigationView, here I set it to a ridiculous 100dp:

enter image description here

  • changing the size of the icons
  • setting bottom_navigation_notification_padding and some other attrs from this answer
  • looking for some info in the material release notes

I was unable to find any "known issue" related to my problem. What am I missing?


Solution

  • In com.google.android.material:material v1.3.0 and above you can use setVerticalOffset or setHorizontalOffset of BadgeDrawable to move the Badge vertically or horizontally with a specific amount in pixels.

    setVerticalOffset(int px)

    Sets how much (in pixels) to vertically move this badge towards the center of its anchor.

    setHorizontalOffset(int px)

    Sets how much (in pixels) to horizontally move this badge towards the center of its anchor.

    Example:

    val menuItemId: Int = bottomNavigation.getMenu().getItem(1).getItemId()
    val badge: BadgeDrawable = bottomNavigation.getOrCreateBadge(menuItemId)
    badge.setVisible(true)
    badge.setNumber(4)
    badge.setVerticalOffset(10) //value in pix
    badge.setHorizontalOffset(-10) //value in pix
    

    Result with and without offset:

    no_offset with_offset