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

8

12

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


Calie answered 29/11, 2017 at 14:44 Comment(4)
you want a library for that or just the code to change the size of the items?Wandy
@HarshitAgrawal if there is already a library that is capable of doing this it would be perfect, otherwise I am looking for the cleanest way to code this.Calie
see my answer below I am typing a code :)Wandy
Check https://mcmap.net/q/1008054/-new-bottom-layout-from-googleVav
M
12
<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

Marinmarina answered 1/9, 2018 at 19:31 Comment(0)
C
5

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.

Calie answered 1/12, 2017 at 10:3 Comment(0)
T
2

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);
Tamikatamiko answered 29/8, 2018 at 7:19 Comment(1)
This is definitely the simplest way to just increase the size of a specific icon. Wanted to add that if you are using androidx instead of the support library, you would use R.id.icon instead of android.support.design.R.id.icon. Also, if it's not clear, you would get the menuView in the same way that fmaccaroni did: BottomNavigationView bottomNavigationView = (BottomNavigationView) activity.findViewById(R.id.bottom_navigation_view); BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationView.getChildAt(0);Prager
W
1

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.

Wandy answered 29/11, 2017 at 14:56 Comment(9)
@Calie okay Louis let me thinkWandy
@Calie have a look at my edited answer. Hope this library helps in what you want. Do let me know for further issues.Wandy
If this helps you accept the answer to this question so that other users who come looking for the same problem can be helped too. :)Wandy
I have thought of solving your problem by one more way. Let me know the feedback of this library first whether it solved the problem.Wandy
I had a look at it but I did not find anything useful for my use case, thanks anyway !Calie
@Calie Please check my updated answer you solve your problem without using any library.Wandy
even if the image look bigger it will be contained inside the bottom bar so that won't helpCalie
stackoverflow does not work this way, upvotes depends on the utility of content, not on the effort that has been put into it. I truely appreciate your help but since it was not useful to me I will not upvote it. Refer to this article for more informations.Calie
@Calie Refer to the answer mentioned it says "you can use upvotes as you see fit" else I leave it to you :)Wandy
A
1

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!

Aflcio answered 15/5, 2018 at 8:1 Comment(4)
you can't position items in a way a BottomNavigationView does with BottomAppBar. It will work as a toolbar for options, rather than a navigation componentDorsy
it is not a solution for thatMarkettamarkey
The answer doesn't answer the question. Menu items are not showing horizontally as in ButtonNavigationAspergillosis
A bottom app bar should be not used for navigation. Pls read the material guidelines for app bar. m2.material.io/components/app-bars-bottom#usageSchoolbag
X
0

Taking this as reference you can iterate for each children of your BottomNavigationView and change the size of the specified item:

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();
    // If it is my special menu item change the size, otherwise take other size
    if (i == 2){
        // set your height here
        layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, displayMetrics);
        // set your width here
        layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, displayMetrics);
    }
    else {
        // 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);
}
Xeniaxeno answered 29/11, 2017 at 14:56 Comment(0)
T
0

I achieved same UI using Frame layout. Here is the code

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph_home" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/background_white_rounded_top"
        app:itemTextColor="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:menu="@menu/bottom_nav_bar_home_items"
        app:labelVisibilityMode="unlabeled">

    </com.google.android.material.bottomnavigation.BottomNavigationView>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <ImageView
            android:id="@+id/toggle_alignment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_home_scan" />

    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

and do not give icon for middle item.

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/firstFragment"
            android:icon="@drawable/ic_one"
            android:title="" />
        <item
            android:id="@+id/secondFragment"
            android:icon="@drawable/ic_two"
            android:title="" />
        <item
            android:id="@+id/thirdFragment"
            android:title="" />
        <item
            android:id="@+id/fourthFragment"
            android:icon="@drawable/ic_four"
            android:title=""/>
        <item
            android:id="@+id/fifthFragment"
            android:icon="@drawable/ic_five"
            android:title="" />
    </group>
</menu>
Trug answered 19/12, 2021 at 6:50 Comment(0)
I
0

For Androidx BottomNavigationView

iterate over each child and change icon size with 'setIconSize()' method (consider @SuppressLint("RestrictedApi"))

val menuView: BottomNavigationMenuView = bottomNavigationView.getChildAt(0) as BottomNavigationMenuView
        for (i in 0 until menuView.childCount) {
            if (i == 3) {
                val displayMetrics: DisplayMetrics = resources.displayMetrics
                (menuView.getChildAt(i) as NavigationBarItemView).setIconSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 41f, displayMetrics).toInt())
            }
        }
Inveterate answered 3/2, 2022 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.