Search code examples
androidkotlinmenuitembottomnavigationviewclickable

Android BottomNavigationView item text not clickable


I'm using a BottomNavigationView but somehow I can't navigate to another item when I exactly click on the item's text because the click gets intercepted. This is a big problem as the text takes up half of the button. If I do a longpress it actually selects the text... Here is my code:

build.gradle

implementation "com.google.android.material:material:1.1.0"

I've also tried 1.3.0-alpha01 but the problem still persists.

OnNavigationItemSelectedListener in my activity.

private fun getBottomNavigationItemSelectedListener() = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    when (item.itemId) {
        bottomNavigation.selectedItemId -> {
            false
        }
        R.id.bottom_navigation_overview -> {
            navigateTo<OverviewActivity>()
            true
        }
        R.id.bottom_navigation_settings -> {
            navigateTo<SettingsActivity>()
            true
        }
        R.id.bottom_navigation_help -> {
            navigateTo<HelpActivity>()
            true
        }
        else -> false
    }
}

layout of the activity

<?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">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragmentContainer"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/bottomNavigation" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:menu="@menu/bottom_navigation_menu"
        app:layout_constraintTop_toBottomOf="@id/fragmentContainer"
        app:labelVisibilityMode="labeled"
        app:itemHorizontalTranslationEnabled="false"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

menu layout

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/bottom_navigation_overview"
        android:enabled="true"
        android:icon="@drawable/ic_bottom_nav_overview"
        android:title="@string/BottomNavigation_overview" />
    <item
        android:id="@+id/bottom_navigation_settings"
        android:enabled="true"
        android:icon="@drawable/ic_bottom_nav_settings"
        android:title="@string/BottomNavigation_settings" />
    <item
        android:id="@+id/bottom_navigation_help"
        android:enabled="true"
        android:icon="@drawable/ic_bottom_nav_help"
        android:title="@string/BottomNavigation_help" />
</menu>

When I turn on the layout boundaries it is clear that the item text is the problem:

First item selected (no problem) first item

Tried to selected second item but the text intercepts the click second item with no luck

What should I do so the item text doesn't intercept the click? I don't see what I'm doing different from the examples that android provides, and I doubt that this is the default behaviour.


Solution

  • Just when I've finished writing this question I've found the cause of the problem. We've made every single TextView in our app selectable with a style.

    themes.xml

    <style name="BaseTheme" parent="Theme.MaterialComponents.Light">
        <item name="android:textViewStyle">@style/TextViewStyle</item>
    </style>
    

    styles.xml

    <style name="TextViewStyle" parent="Widget.MaterialComponents.TextView">
        <!-- other styling -->
        <item name="android:textIsSelectable">true</item>
    </style>
    

    As a result the TextView of the BottomNavigationView-Item will intercept all clicks.

    We still want most of our TextViews to be selectable, just not the TextView within the BottomNavigationView. So I created a new theme that inherits from the base-theme and a new style that inherits the other TextView-style:

    themes.xml

    <style name="BottomNavigationTheme" parent="BaseTheme">
        <item name="android:textViewStyle">@style/TextViewStyle.NoTextSelection</item>
    </style>
    

    styles.xml

    <style name="TextViewStyle.NoTextSelection" parent="@style/TextViewStyle">
        <item name="android:textIsSelectable">false</item>
    </style>
    

    Next I added the theme to the BottomNavigationView located in my layout

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:theme="@style/BottomNavigationTheme"
        app:menu="@menu/bottom_navigation_menu"
        app:layout_constraintTop_toBottomOf="@id/fragmentContainer"
        app:labelVisibilityMode="labeled"
        app:itemHorizontalTranslationEnabled="false"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
    

    And this solved my problem.