Android : Get view Reference to a Menu Item

84,911

Solution 1

You can achieve this by providing your menu item with an actionViewClass property in xml and then you will be able to get the pivot view u wanted. The code would be something like this

<item
    android:id="@+id/menu_find"
    android:showAsAction="ifRoom"
    android:actionViewClass="android.widget.ImageButton"
    />

In your OnCreateOptionsMenu do this

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.menu_search, menu);
    locButton = (ImageButton) menu.findItem(R.id.menu_find).getActionView();
    locButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            createPopup();
            mQuickAction.show(v);
        }
    });
    return true;
}

Solution 2

Old question, but I ran into some issues with the actionViewClass attribute. For anyone who runs into this later...

Calling findViewById(R.id.mnu_item) in onOptionsItemSelected will return a View anchor.

QuickActions on the MenuItems aren't good design, but I found that they are the simplest way to implement submenus with custom backgrounds.

Solution 3

Inorder to get reference Views of menu items we need to do this,

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.section, menu);

    new Handler().post(new Runnable() {
        @Override
        public void run() {

            final View menuItemView = findViewById(R.id.action_preview);
            // SOME OF YOUR TASK AFTER GETTING VIEW REFERENCE

        }
    });


    return true;
}

Solution 4

An update for anyone that want to find the menu view item for other reasons (like I wanted).

If you have access to and use AppCompat's Toolbar there is a way. It's not the most efficient way, but it's the easiest way I've found to access the menu item's view.

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);

    // Find Menu
    for (int toolbarChildIndex = 0; toolbarChildIndex < toolbar.getChildCount(); toolbarChildIndex++) {
        View view = toolbar.getChildAt(toolbarChildIndex);

        // Found Menu
        if (view instanceof ActionMenuView) {
            ActionMenuView menuView = (ActionMenuView) view;

            // All menu items
            for (int menuChildIndex = 0; menuChildIndex < menuView.getChildCount(); menuChildIndex++) {
                ActionMenuItemView itemView = (ActionMenuItemView) menuView.getChildAt(menuChildIndex);
                // Do something to itemView...
            }
        }
    }
}

Solution 5

Universal code which also works on Android 10

/**
* pass toolbar and menu item id, i.e. R.id.menu_refresh
*/
@Nullable
@Throws(
    IllegalAccessException::class,
    NoSuchFieldException::class
)
fun getMenuItemView(toolbar: Toolbar?, @IdRes menuItemId: Int): View? {
    val mMenuView: Field = Toolbar::class.java.getDeclaredField("mMenuView")
    mMenuView.setAccessible(true)
    val menuView: Any? = mMenuView.get(toolbar)
    (menuView as ViewGroup).children.forEach {
        if(it.id == menuItemId) {
            return it
        }
    }
    return null
}
Share:
84,911
Yashwanth Kumar
Author by

Yashwanth Kumar

Android developer and loves to play games.

Updated on July 05, 2022

Comments

  • Yashwanth Kumar
    Yashwanth Kumar almost 2 years

    I plan to use quick actions UI pattern in my application. Android Quick Actions UI Pattern . The quick action window needs a pivot view to stick to.

        quickAction.show(View pivotView);
    

    I intend to use quick action for the menu Item, I can get access to the item that is clicked. But the problem is i need to reference a view from the menu item so that i can pass it to the quick action.

    How can i get reference to a view in the menuItem that is selected.

  • Igor Čordaš
    Igor Čordaš almost 11 years
    Thank you very much! I had a weird problem where viewfinder would find a spiner in actionbar when on android 4.1 but on 4.2 it just returned null,this fixed it.
  • Leebeedev
    Leebeedev about 9 years
    I guess you will need to click the 'menuItem' at least once before you could get the 'menuItem' 'view' anchor.
  • loadedion
    loadedion about 9 years
    Right, the findViewById() call would have to be done at run time
  • AnkitRox
    AnkitRox over 8 years
    setOnMenuItemClickListener will be helpful for me, in case you want to perform direct operation with Menu Item
  • EngineSense
    EngineSense almost 8 years
    use app:actionViewClass if you use recent library. (res-auto)
  • abhy
    abhy almost 8 years
    Thanks @ASH answer failed if we put actionViewClass. This is working great.
  • user25
    user25 about 6 years
    the best way, without creating any custom view and setactionview
  • brucemax
    brucemax over 4 years
    It's so ugly (thanks api) but this is really work solution, thanks a lot
  • Kishy Nivas
    Kishy Nivas over 2 years
    Doesn't work in api 28
  • Tomas M
    Tomas M about 2 years
    You are amazing, this worked for me. Thanks so much for sharing!