Android : Get view Reference to a Menu Item
Asked Answered
M

6

71

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.

Mide answered 23/12, 2011 at 9:30 Comment(3)
londatiga.net/it/how-to-create-quickaction-dialog-in-android have you used this link..Blubberhead
@NikhilreddyGujjula link is not working.Mide
long back i have tried it has worked for me but i am not having code for me sry..Blubberhead
G
115

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;
}
Glauce answered 2/3, 2012 at 7:5 Comment(3)
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.Kingsbury
setOnMenuItemClickListener will be helpful for me, in case you want to perform direct operation with Menu ItemResume
use app:actionViewClass if you use recent library. (res-auto)Foreword
M
46

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.

Mousse answered 17/4, 2013 at 20:59 Comment(3)
I guess you will need to click the 'menuItem' at least once before you could get the 'menuItem' 'view' anchor.Comatulid
Right, the findViewById() call would have to be done at run timeMousse
Thanks @Glauce answer failed if we put actionViewClass. This is working great.Booker
A
27

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;
}
Adrenocorticotropic answered 1/1, 2018 at 5:38 Comment(4)
the best way, without creating any custom view and setactionviewWelsh
It's so ugly (thanks api) but this is really work solution, thanks a lotWellmannered
Doesn't work in api 28Spearmint
You are amazing, this worked for me. Thanks so much for sharing!Scots
G
6

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...
            }
        }
    }
}
Globular answered 9/9, 2016 at 11:27 Comment(0)
T
1

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
}
Tamayo answered 23/6, 2020 at 11:19 Comment(1)
Soon this will be blocked on the getDeclaredField had to add this @SuppressLint("SoonBlockedPrivateApi")Perch
M
-2

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
}
Materially answered 5/3, 2017 at 9:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.