Android : Get view Reference to a Menu Item

AndroidViewMenuMenuitemQuickaction

Android Problem Overview


I plan to use quick actions UI pattern in my application. https://stackoverflow.com/questions/3059155/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.

Android Solutions


Solution 1 - Android

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

http://schemas.android.com/apk/res/android" >

<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 - Android

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 - Android

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 - Android

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 - Android

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
}

Solution 6 - Android

Kotlin!!

override fun onCreateOptionsMenu(Menu menu): Boolean {

  /*Adding menu items to action bar*/
  menuInflater.inflate(R.menu.main, menu)

  /*Getting menu item*/
  val locButton: MenuItem = menu.findItem(R.id.menu_find)

  /*Creating click listener*/
  locButton.setOnMenuItemClickListener{
    /*TODO: Handle it*/
    true
  }

  return true;
}

Solution 7 - Android

in the main activity class, best to override the onOptionsItemSelected(...) method; should be something as below:

public boolean onOptionsItemSelected(MenuItem item) {
  // the id is of type int
  int someId = item.getItemId();
  // can use an if() or switch() statement to check if id is selected
  //a Toast message can be used to show item is selected
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYashwanth KumarView Question on Stackoverflow
Solution 1 - AndroidASHView Answer on Stackoverflow
Solution 2 - AndroidloadedionView Answer on Stackoverflow
Solution 3 - AndroidjazzbpnView Answer on Stackoverflow
Solution 4 - AndroidMatteus MagnussonView Answer on Stackoverflow
Solution 5 - AndroidShahbaz HashmiView Answer on Stackoverflow
Solution 6 - AndroidYogiView Answer on Stackoverflow
Solution 7 - AndroidodinsView Answer on Stackoverflow