Android : Get view Reference to a Menu Item
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
}
Comments
-
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š almost 11 yearsThank 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 about 9 yearsI guess you will need to click the 'menuItem' at least once before you could get the 'menuItem' 'view' anchor.
-
loadedion about 9 yearsRight, the
findViewById()
call would have to be done at run time -
AnkitRox over 8 yearssetOnMenuItemClickListener will be helpful for me, in case you want to perform direct operation with Menu Item
-
EngineSense almost 8 yearsuse app:actionViewClass if you use recent library. (res-auto)
-
abhy almost 8 yearsThanks @ASH answer failed if we put actionViewClass. This is working great.
-
user25 about 6 yearsthe best way, without creating any custom view and setactionview
-
brucemax over 4 yearsIt's so ugly (thanks api) but this is really work solution, thanks a lot
-
Kishy Nivas over 2 yearsDoesn't work in api 28
-
Tomas M about 2 yearsYou are amazing, this worked for me. Thanks so much for sharing!