3

Background

I'm trying to have a bit larger BottomNavigationView (height is a bit bigger), while also making each item icon have a top indicator that it's selected.

Something like that, but with larger height:

enter image description here

It's a bit hard to see it on the screenshot, but the indicator is shown at the very top of the BottomNavigationView's item, right below the BottomNavigationView's shadow.

The problem

When I set a larger height, I get each item still take smaller height, so the indicator doesn't look at the top:

enter image description here

Not only that, but because I used itemBackground to set the background of each item to have the indicator, it now doesn't have the background used for the clicking effect.

What I've found

About the height, I've found this question on StackOverflow, of changing the height. The only solution there is to override the library's dimensions. In this case, it's only this:

<dimen name="design_bottom_navigation_height" tools:override="true">...</dimen>

However, this only solves the issue of putting the indicator at the top.

Plus, it looks like a dirty solution, to set the dimension forcefully for the library, and as I wrote, because I used itemBackground , it doesn't have the normal clicking effect anymore.

Here's the relevant code, modified just a bit from the wizard of Android Studio for making "Bottom Navigation Activity". The rest is the same as there :

activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/container" xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity">

    <TextView
        android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/activity_vertical_margin" android:text="@string/title_home"
        app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view" android:layout_width="0dp"
        android:layout_height="@dimen/tabs_height" android:layout_marginEnd="0dp"
        android:layout_marginStart="0dp" android:background="?android:attr/windowBackground" app:itemBackground="@drawable/activity_main__tab_background"
        app:labelVisibilityMode="unlabeled" app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu"/>

</androidx.constraintlayout.widget.ConstraintLayout>

dimens.xml

<dimen name="tabs_height">64dp</dimen>
<dimen name="design_bottom_navigation_height" tools:override="true">@dimen/tabs_height</dimen>

activity_main__tab_background.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <layer-list>
            <item android:gravity="top">
                <shape android:shape="rectangle">
                    <size android:height="2dp"/>
                    <solid android:color="#07a5ea"/>
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

The question

How can I have the indicator at the top, while having a larger BottomNavigationView and without losing the clicking effect?

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Tried the same thing...running as expected with click events, indicator at top and custom height. Is there anything I misunderstood about question? – Naitik Soni Jun 24 '19 at 14:06
  • You see clicking effect ? And you don't see extra space? How come? See attached project here: https://ufile.io/vuyygja9 . Please try it out. Set an even larger height than what I've set. Try to click the items too. – android developer Jun 24 '19 at 14:43
  • I just removed comment from dimens file...for this line @dimen/tabs_height and it is working... – Naitik Soni Jun 25 '19 at 07:45
  • @NaitikSoni I don't understand. What is working? – android developer Jun 25 '19 at 08:02
  • Indicator at top, with click event and custom height. all things are pretty working. – Naitik Soni Jun 25 '19 at 08:22
  • @NaitikSoni Can you please share the code and/or project? What exactly did you do? Are the sure the indicator is indeed at the top, without spacing between the item and the shadow of the BottomNavigationView, as I've shown on the screenshot? Try setting it to have even larger height than what I've set (example: 100dp), and see if it's at the top or has space. – android developer Jun 25 '19 at 08:28
  • Tried with 120dp. [see image](https://i.stack.imgur.com/R3TIq.jpg) – Naitik Soni Jun 25 '19 at 08:43
  • How odd. Can you please share what you did? Maybe upload the project to the same website I have? – android developer Jun 25 '19 at 09:24
  • Can I know the version of a device you are checking on?? Mine is android 9. – Naitik Soni Jun 25 '19 at 09:31
  • I've tested on Galaxy Note 8 with Android 8.0. I now tried to have only `design_bottom_navigation_height` set, and there is still no clicking effect. – android developer Jun 25 '19 at 09:35
  • So you can't click on any tab/icon? and the value of textview is not changing...Is that so? – Naitik Soni Jun 25 '19 at 09:37
  • I didn't say I can't click. I said there is no clicking effect. There is no ripple, for example. If I remove the `app:itemBackground` part, there is a clicking effect. Also, as for the height of the `BottomNavigationView`, as I wrote, I wish to avoid using the hack/workaround I've mentioned if possible (of `design_bottom_navigation_height `) . If there is a more reliable way to do it, it would be better. – android developer Jun 25 '19 at 09:41
  • Oh...sorry. there is where I misunderstood. Haven't thought of ripple effect. But still I am trying now. – Naitik Soni Jun 25 '19 at 09:54
  • Please also try to avoid `design_bottom_navigation_height` . I mentioned it only because that's what I've found, and I think that if there is a better alternative, it's worth use it instead. – android developer Jun 25 '19 at 10:31

1 Answers1

5

the best solution is to change the margin of the item imageView from kotlin code on runtime here is the code

private fun navigationImagesMargin(view: View) {
        if (view is ViewGroup) {
            for (i in 0 until view.childCount) {
                val child = view.getChildAt(i)
                navigationImagesMargin(child)
            }
        } else if (view is ImageView) {
            val param = view.layoutParams as ViewGroup.MarginLayoutParams
            param.topMargin = convertDpToPx(14)
            view.layoutParams = param
        } 
    }
fun convertDpToPx(dp: Int): Int {
    return Math.round(dp * (resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT))
}

in the onCreate function call navigationImagesMargin function on the BottomNavigation View

navigationImagesMargin(binding.spBottomNavigation)

but this solution requires to recall navigationImagesMargin function everytime the view revalidated i.e. in the onItemClick listener here is the code for that

 binding.spBottomNavigation.setOnNavigationItemSelectedListener { it->
            binding.spBottomNavigation.post {
                navigationImagesMargin(binding.spBottomNavigation)
            }
            true
        }

in that way the images will stay where you aimed them to be on first launch

this is a link for tiny repo that include the full code https://github.com/abdulmalekDery/BottomNavigationControl

Abdulmalek Dery
  • 996
  • 2
  • 15
  • 39
  • 1
    Sorry but I forgot about this. If you have a tiny Github sample to show me, I can test it and mark it as answered. – android developer Jan 29 '21 at 20:52
  • ok..gonna send you link to a project asap – Abdulmalek Dery Jan 30 '21 at 09:02
  • 1
    sorry for delay I've edited the answer to include a link for a tiny git repo https://github.com/abdulmalekDery/BottomNavigationControl – Abdulmalek Dery Jan 30 '21 at 13:59
  • 1
    Seems to work, but it has an issue that it adds the fragments so they get merged (text on top of text), and the repository doesn't put a link to here. Is the code you wrote here the only thing that's needed? – android developer Jan 30 '21 at 14:56
  • actually..I'm using the navigation component library in my original project..I've created that repo just to demonstrate the solution for your question....I can update the repo to include the library if you wish..just let me know if you want that – Abdulmalek Dery Jan 30 '21 at 21:38
  • 1
    Yes please. Why does it have the issue though? Did you add fragment on top of fragment, and had them transparent, or something? – android developer Jan 31 '21 at 00:25
  • 1
    Hi @android developer I've added the navigation component support you can check it out... don't forget to mark my answer as accepted answer if so.. Welcome any time my friend! – Abdulmalek Dery Feb 01 '21 at 09:35
  • Seems to work fine now, but you didn't add a link to here on the repository's "README.md" file : https://github.com/abdulmalekDery/BottomNavigationControl . The description is empty. – android developer Feb 01 '21 at 10:36
  • 1
    Anyway I mark it as the answer, but please put a link on the repository to here. – android developer Feb 01 '21 at 14:22
  • 1
    thanks...I've added the link of the question and answer to README.md – Abdulmalek Dery Feb 01 '21 at 20:30