3

I want to change the size of only ONE icon (3rd icon) out of the 5 icons I have used in my bottom navigation view.

I want The Center icon big like:

My Bottom Nav View

This is what I have tried:

private fun setReportPainIconSize(){
        val bottomNavigationView =
            findViewById<BottomNavigationView>(R.id.navigationBottomView)

    val menuView: BottomNavigationMenuView =
            bottomNavigationView.getChildAt(0) as BottomNavigationMenuView
     
    val iconView: View = menuView.getChildAt(2) **//TO GET REFERENCE OF 3RD ITEM**
                    .findViewById(androidx.core.R.id.icon)
           
    val layoutParams: ViewGroup.LayoutParams = iconView.layoutParams
            val displayMetrics: DisplayMetrics = resources.displayMetrics
            layoutParams.height = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 47F,
                displayMetrics
            ).toInt()
            layoutParams.width = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 44F,
                displayMetrics
            ).toInt()
            iconView.layoutParams = layoutParams
    }

But on running my app crashes and the error message I get is :

Caused by: java.lang.NullPointerException: menuView.getChildAt(2)
     …(androidx.core.R.id.icon) must not be null

How do I accomplish it? ? Pls help!

Sparsh Dutta
  • 2,450
  • 4
  • 27
  • 54
  • Try creating a custom Bottom Navigation Bar, where you can be able to change Icons size. –  Aug 17 '22 at 12:00

1 Answers1

2

Using the latest Material Design library (com.google.android.material:material:1.6.1) the id to get a reference to the menu icon View is the com.google.android.material.R.id.navigation_bar_item_icon_view

So you can change programmatically a specific menu item size in BottomNavigationView like the below sample:

//find the icon view for the menu item index 1
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView)
val menu = bottomNavigationView.menu
val menuItem = menu.getItem(1)
val navigationBarItemView: NavigationBarItemView = bottomNavigationView.findViewById(menuItem.itemId)
val iconView: View = navigationBarItemView.findViewById(com.google.android.material.R.id.navigation_bar_item_icon_view)

//set the new width and height for the iconView in pixels. You can change also the bottom margin of the icon View.
val iconViewParams: FrameLayout.LayoutParams = iconView.layoutParams as FrameLayout.LayoutParams
iconViewParams.width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 44F, resources.displayMetrics).toInt()
iconViewParams.height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 47F, resources.displayMetrics).toInt()
iconViewParams.bottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 35F, resources.displayMetrics).toInt()
iconView.layoutParams = iconViewParams

Also to draw something above the BottomNavigationView like the centered icon you have to make all ViewGroup parents in BottomNavigationView to have clipChildren = false and clipToPadding = false using a recursive function like the below:

fun recursiveClipChildrenAndClipToPadding(parent: ViewGroup) {

    if(parent is BottomNavigationView){
        val bottomNavigationView = parent as BottomNavigationView
        bottomNavigationView.clipChildren = false
        bottomNavigationView.clipToPadding = false
    }
    for (i in 0 until parent.childCount) {
        val child = parent.getChildAt(i)
        if (child is ViewGroup) {
            val vGroup = child as ViewGroup
            vGroup.clipChildren = false
            vGroup.clipToPadding = false
            recursiveClipChildrenAndClipToPadding(vGroup)
        }
    }
}

and you have to call it like this:

recursiveClipChildrenAndClipToPadding(bottomNavigationView)

A sample result i have made using some default icons is like the below:

custom_menu_item_position

MariosP
  • 8,300
  • 1
  • 9
  • 30