NavigationView menu items with actionLayout. How can I set those action layout's attribute for each item?
Asked Answered
R

1

0

Following this answer, I learned how to add extra views to the NavigationView's menu items, by adding an action layout. My question is, essentially, how can I tweak each of those individual actionLayouts dynamically, through Java?

In my case, instead of adding a "switch" to the menu items, I used actionLayouts to add an extra icon that will show a state for that item. It's a boolean state, so I want to show the difference either by changing the extra icon dynamically or by toggling visibility.

So I have a menu.xml like this one for my NavigationView:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:showIn="navigation_view">

    <group android:id="@+id/menu_group"
        android:checkableBehavior="single" >
        <item
            android:id="@+id/menu_item1"
            android:icon="@drawable/some_main_icon"
            app:actionLayout="@layout/myflag_actionlayout"
            android:title="OPTION 1" />
        <item
            android:id="@+id/menu_item2"
            android:icon="@drawable/some_main_icon"
            app:actionLayout="@layout/myflag_actionlayout"
            android:title="OPTION 2" />
        <!-- etc. -->
    </group>
</menu>

...and my myflag_actionlayout.xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:background="#444444"
    android:layout_width="wrap_content"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/lockedIcon"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        app:srcCompat="@android:drawable/ic_lock_idle_lock" />
</LinearLayout>

So it looks like this more or less:

my_new_menu_items

Now I wonder: how can I get each of those menu items' instances, access their <ImageView> instance from Java, and change each lockedIcon's ImageView depending on a boolean variable? (For instance, toggling the ImageView's visible attribute or changing the image for app:srcCompat attribute) Should I use some findViewById(R.id.lockedIcon) for this task, or is it a bad idea and I should do it another way?

EDIT:

Just now I recall, I already did something similar to access those "NavigationView items" by Java, and add a string to the counter editing the title:

NavigationView nav_v = findViewById(R.id.navigation_view);
MenuItem nav_option1 = nav_v.getMenu().findItem(R.id.menu_item1);
nav_option1.setTitle(getString(R.string.nav_option1_title) + " -> " + some_counter);

Maybe i can from nav_option1 invoke some method to access its action layout?

Regnant answered 11/9, 2022 at 23:31 Comment(3)
Even though I do not use Kotlin, I'm not too afraid of it. I could convert it to Java most probably anyway...Regnant
So if you know how to get a particular MenuItem, why aren't you using getActionView()?Sign
@Sign because I just didn't knew it existed... let's try this out...Regnant
R
1

Good! @ianhanniballake 's suggested method worked like a charm. If I do this:

NavigationView nav_v = findViewById(R.id.navigation_view);
MenuItem nav_option1 = nav_v.getMenu().findItem(R.id.menu_item1);
ImageView option1_lock_icon = nav_option1.getActionView().findViewById(R.id.lockedIcon);

And from there, I could do whatever I want with this ImageView:

// Toggle visibility approach
if (item_locked) {
    option1_lock_icon.setVisibility(View.VISIBLE);
} else {
    option1_lock_icon.setVisibility(View.INVISIBLE);
}

// Change icon approach
string uri = "";
if (item_locked) {
    uri = "@android:drawable/ic_lock_idle_lock";
} else {
    uri = "@android:drawable/ic_menu_view";
}
int imageResource = getResources()
      .getIdentifier(uri,
                     null,
                     getPackageName()
      );
option1_lock_icon.setImageDrawable(
       getResources().getDrawable(imageResource)
);

Also, it looks like I can do more or less the same with any object I add to those "action layouts". :-)

Regnant answered 12/9, 2022 at 3:4 Comment(1)
Would self-accepting my answer too soon be unfair? I wonder...Regnant

© 2022 - 2024 — McMap. All rights reserved.