How to change the size and shape of a particular bottom bar navigation item

I am trying to implement this bottom bar which contains an item with a bigger size and a different shape than the other ones.

bottom bar

Is there a non-hacky way to achieve this using the native Bottom navigation component ? I guess not because it does not seem compliant with Material Design specs.

Otherwise, what would be the best approach to follow ? I see only 2 ways to achieve this but none of them seems reliable to me.

  • For every "small item", adding a transparent bar at the top of the drawable to reach the size of the camera icon.
  • Implementing a 5 items bottom bar with a "ghost item" in the middle, on top of which I could place some other component. This would require this component to be coupled with the bottom bar.

EDIT

This is what I obtained by increasing the icon size as suggested by Harshit and fmaccaroni.

When the item is not selected :

item_selected

When the item is selected :

item_selected

Pro: The icon is bigger than the other ones

Cons: It is still contained inside the bottom bar. Also, it is not centered vertically when selected


Answers

After a few research I came across this library. They did not provide what I was looking for, but they implemented this behavior in one of their samples, which was pretty close to what I needed.

This is what I got by reusing their idea (tested only on API 23):

<blockquote class="imgur-embed-pub" lang="en" data-id="a/0Oypk"><a href="//imgur.com/0Oypk"></a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>

It looks decent, but I do not like the implementation since the bottom navigation is now split between two components.

The idea is to create an empty item in the middle of the bottom bar, and to add a floating action button on top of it, to create the illusion that it is part of the bottom bar.

Here is the layout of my bottombar and floating navigation button:

<com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx
    android:id="@+id/navigation"
    android:layout_width="match_parent"
    android:layout_height="56dp"
    android:layout_gravity="bottom"
    app:elevation="0dp"
    app:itemIconTint="@drawable/menu_item_selector"
    app:itemTextColor="@drawable/menu_item_selector"
    app:layout_constraintBottom_toBottomOf="parent"
    app:menu="@menu/navigation_items" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:focusable="true"
    app:backgroundTint="@color/white"
    app:borderWidth="0dp"
    app:elevation="0dp"
    app:fabSize="mini"
    app:layout_constraintBottom_toBottomOf="@id/navigation"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:srcCompat="@drawable/camera_icon" />


Navigation bar items :

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    <item
        android:id="@+id/action_around_me"
        android:icon="@drawable/ic_bottombar_around_me"
        tools:ignore="MenuTitle" />

    <item
        android:id="@+id/action_my_projects"
        android:icon="@drawable/ic_bottombar_projects"
        tools:ignore="MenuTitle" />

    <!-- Here is the trick -->
    <item
        android:id="@+id/empty"
        android:enabled="false"
        tools:ignore="MenuTitle" />

    <item
        android:id="@+id/action_notifications"
        android:icon="@drawable/ic_bottombar_notification"
        tools:ignore="MenuTitle" />

    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/ic_bottombar_settings"
        tools:ignore="MenuTitle" />
</menu>

Everytime I the FAB button is clicked, I disable the bottom bar :

private void disableBottomBar() {
    Menu menu = navigationBar.getMenu();
    for (int i = 0; i < menu.size(); i++) {
        // The third item is a an empty item so we do not do anything on it
        if (i != 2) {
            menu.getItem(i).setCheckable(false);
        }
    }
}

Same thing with setCheckable(true) when a bottom bar icon is clicked.

Hope this helps.

Posted on by Louis
<android.support.design.widget.BottomNavigationView
    android:id="@+id/navigation"
    android:layout_width="match_parent"
    android:layout_height="56dp"
    android:layout_alignParentBottom="true"
    android:background="?android:attr/windowBackground"
    app:itemIconTint="@color/colorPrimary"
    app:itemTextColor="@android:color/black"
    app:menu="@menu/navigation"
    android:clipChildren="false">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:layout_gravity="center"
        android:layout_marginBottom="8dp"
        app:elevation="6dp"
        android:scaleType="center" />
</android.support.design.widget.BottomNavigationView>


also add android:clipChildren="false" to root layout

Posted on by Siddhesh Shirodkar

the simple way is using setScaleX and setScaleY. for example:

final View iconView = 
menuView.getChildAt(2).findViewById(android.support.design.R.id.icon);
iconView.setScaleY(1.5f);
iconView.setScaleX(1.5f);

Posted on by royaB

Since the last Material update (2018), it's possible to do so with native UI elements:

  • BottomAppBar with app:fabAttached attribute
  • FloatingActionButton with app:layout_anchor relating the BottomAppBar
  • Enjoy the alignment with app:fabAlignmentMode

Alignment center

You can relate to this great Medium article for more new material elements and more details about this one.

Hope it helps you!

Posted on by DPalagi

The icons size in Bottom Bar navigation can be changed programmatically by

BottomNavigationView bottomNavigationView = (BottomNavigationView) 
activity.findViewById(R.id.bottom_navigation_view);

BottomNavigationMenuView menuView = (BottomNavigationMenuView) 
bottomNavigationView.getChildAt(0);

for (int i = 0; i < menuView.getChildCount(); i++) {
final View iconView = 
menuView.getChildAt(i).findViewById(android.support.design.R.id.icon);

final ViewGroup.LayoutParams layoutParams = iconView.getLayoutParams();

final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
// set your height here
layoutParams.height = (int) 
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, displayMetrics);

// set your width here
layoutParams.width = (int) 
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, displayMetrics);

iconView.setLayoutParams(layoutParams);
}

I did something just like this to change the size of the bottom bar navigation items as desired.

And here is what you can do:

  1. Take a large sized image of the same image that you want to display bigger in size when clicked and store it in that drawable folder.

  2. Than apply when the navigation bottom bar that particular item is clicked than set the previous smaller image with the larger image.

And you can have a look at this library use this library to solve your problem.

Posted on by HarshitMadhav