Search code examples
androidnavigation-drawerandroid-design-librarynavigationviewandroid-navigationview

Propagate navigation view state to action layout


I am using the android support library to create a navigation drawer.

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        android:background="@color/white"
        app:headerLayout="@layout/nav_header_landing"
        app:menu="@menu/activity_dashboard_drawer"
        app:theme="@style/MyActionButtonStyle"/>

I am creating custom menu items using the actionLayout

<group android:checkableBehavior="single"
        android:id="@+id/gp_dashboard">
        <item
            android:id="@+id/nav_dashboard"
            app:actionLayout="@layout/layout_dashboard"
            android:icon="@mipmap/ic_dashboard"
            android:title=""/>
    </group>

This is the layout "layout_dashboard"

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:duplicateParentState="true">

    <helpers.customViews.RobotoTextView
        android:id="@+id/dash_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="DASHBOARD"
        app:typeface="robotoMedium"
        android:textColor="@color/nav_header_state_list"
        android:textSize="14sp"/>

    <helpers.customViews.RobotoTextView
        android:id="@+id/dash_subtitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/dash_title"
        android:text="@string/dashboard_txt"
        app:typeface="robotoRegular"
        android:textColor="@color/nav_sub_header_state_list"
        android:textSize="12sp"/>

</RelativeLayout>

Now I want to change the text color of this layout when the menu item is selected. To do so I am using the @color/nav_header_state_list

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/greeny_blue" android:state_checked="true"/>
    <item android:color="@color/greeny_blue" android:state_pressed="true" />
    <item android:color="@color/black"/>
</selector>

But the color remains the same even when the menu item is selected. The pressed state works but the checked state doesn't. Please help me to resolve the issue .


Solution

    • Replace state_checked with state_selected in the nav_header_state_list.xml

    Your nav_header_state_list.xml should look like this:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/greeny_blue" android:state_pressed="true" />
        <item android:color="@color/greeny_blue" android:state_selected="true" />
        <item android:color="@color/black" />
    </selector>
    
    • Declare MenuItem object in the MainActivity.java
    • Add the following logic to the onNavigationItemSelected

    Your MainActivity.java should look like this:

    public class MainActivity extends AppCompatActivity
            implements NavigationView.OnNavigationItemSelectedListener {
    
        MenuItem previousItem;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // ... some code
        }
    
        @Override
        public boolean onNavigationItemSelected(MenuItem item) {
            // Handle navigation view item clicks here.
            int id = item.getItemId();
            // ... some code
    
            if (previousItem != null) {
                View previousActionView = previousItem.getActionView();
                previousActionView.findViewById(R.id.dash_title).setSelected(false);
                previousActionView.findViewById(R.id.dash_subtitle).setSelected(false);
            }
            View actionView = item.getActionView();
            actionView.findViewById(R.id.dash_title).setSelected(true);
            actionView.findViewById(R.id.dash_subtitle).setSelected(true);
            previousItem = item;
    
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
            drawer.closeDrawer(GravityCompat.START);
            return true;
        }
    }