0

Is there a way to put a ring around a selected tab using BottomNavigationView the way Instagram does when you click on the profile tab?

In this case, the profile tab has a gray ring around the photo.

enter image description here

Zain
  • 37,492
  • 7
  • 60
  • 84
Micro
  • 10,303
  • 14
  • 82
  • 120

1 Answers1

1

You'd set the app:itemBackground with a checked state selector with centered oval shape

Selector: drawable/rounded_selector:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <layer-list>
            <item android:gravity="center">
                <shape android:shape="oval">
                    <size android:width="35dp" android:height="35dp" />
                    <stroke android:width="3dp" android:color="@android:color/darker_gray" />
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

And set that to the BottomNavigationView:

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:itemBackground="@drawable/rounded_selector"
    app:labelVisibilityMode="unlabeled" />


Edit

How would you do it if you wanted only one of the tabs to show the circle selector? The way Instagram does it only for the profile.

You'd set that to the menu item by combining drawable layers into LayerDrawable, then set that back to the menu item:

drawable/circle_border

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <stroke android:width="8dp" />
    <solid android:color="@android:color/transparent" />
    <size
        android:width="200dp"
        android:height="200dp" />
</shape>

And in code:

val item = bottomNavView.menu.findItem(R.id.profile_item) // change to the id of the profile item

val border = ResourcesCompat.getDrawable(
    resources,
    R.drawable.circle_border, null
) as GradientDrawable
val layerDrawable = LayerDrawable(arrayOf(item.icon, border))
item.icon = layerDrawable
Zain
  • 37,492
  • 7
  • 60
  • 84
  • How would you do it if you wanted only one of the tabs to show the circle selector? The way instagram does it only for the profile. – Micro Apr 09 '23 at 02:11
  • Just got it. Sorry I didn't use Instagram before. Let me think of it, probably they don't use BNV – Zain Apr 09 '23 at 02:51
  • I like your solution though. It's just I need the circle for only one of the tabs. – Micro Apr 09 '23 at 03:25
  • @Micro Just updated the answer, please have a look – Zain Apr 09 '23 at 15:41
  • I had to detect when a tab was pressed and run the code to add circle_border but it worked. Thank you. – Micro Apr 10 '23 at 09:59