Anchoring a PopupMenu to Navigationview menu items - android

Since this question and its answer didn't show up anywhere, thought I might as well contribute a little for once by sharing the way I found.
So I had this issue with anchoring a PopupMenu object to a NavigationView menu since I couldn't get any items out of it in the form of a view:
//onCreate:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
drawerMenu = navigationView.getMenu();
//onNavigationItemSelected(MenuItem menuItem):
switch (menuItem.getItemId()) {
case R.id.menubutton_submenuButton:
//the following line is merely how I'd imagine it should be
PopupMenu popupMenu = new PopupMenu(this, drawerMenu.findItem(R.id.menubutton_submenuButton));
popupMenu.getMenuInflater().inflate(R.menu.sub_menu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
//handle the inflated menu's buttons here
return true;
}
});
popupMenu.show();
break;
}
So then, the problem is basically where
drawerMenu.findItem(R.id.menubutton_submenuButton));
isn't a View of any sort, which leaves the PopupMenu with nothing to anchor to.

So I figured you can just create an empty view inside the menu item as follows:
create a layout xml file including only the following:
<?xml version="1.0" encoding="utf-8"?>
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
/>
lets call it "view_empty".
Now the menu item should have that empty view layout included inside of it by adding the following line to its item: app:actionLayout="#layout/drawer_empty"
My item looks as follows:
<item
android:id="#+id/menubutton_submenuButton"
android:title="example menu item"
app:actionLayout="#layout/view_empty"/>
Now then, all that's left is just using it:
//onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.menubutton_submenuButton:
MenuItem item = drawerMenu.findItem(R.id.menubutton_submenuButton);
PopupMenu popupMenu = new PopupMenu(this, MenuItemCompat.getActionView(item));
popupMenu.getMenuInflater().inflate(R.menu.sub_menu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
//handle the inflated menu's buttons here
return true;
}
});
popupMenu.show();
break;
What'd happen now is that the PopupMenu would anchor itself to an invisible view inside the menuItem, thus making it look like the container menuItem is the anchor point.

Related

How to make "my account or settings " clickable?

Here is the screen shot of my sidebar navigation bar.
I want to make the items in the sidebar navigation Menu clickable so that I can move to another Activity how can I do this?
You have to treat these as Menu items.
When you set up the navigation bar from the layout XML you attach a menu.xml to it which contains menu items that are then displayed in the navigation bar.
Method 1:
Now from the activity where you have your navigation bar variable you need to get the menu from the navigation view object.
Menu menu = navigation_view.getMenu();
Then you can get individual menuItems from this menu object.
MenuItem myAccount = menu.getItem(0);
MenuItem settingsItem = menu.getItem(1);
MenuItem logoutItem = menu.getItem(2);
Now you can use each of this menuItem objects to set menu click listeners on them and then start the next activity from there. e.g.
myAccount.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
Intent intent = new Intent(context, ToAcitivity.class);
startActivity(intent);
return true;
}
});
Similarly, you can use rest of the objects and make them clickable.
Method 2:
You can also use
navigation_view.setNavigationItemSelectedListener(new
NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case 1:
break;
case 2:
}
return false;
}
});
Second one being more simpler to use

Android: how to open menu where user clicks

Is it possible to open a menu in the exact point where the user has clicked?
I have a custom listview and I'd like to show a menu like the right click on Windows in the point where the user clicks on the listview item.
Absolutely. Take a look at PopupMenu, which lets you do exactly that. Here's an example of how to use it:
listItemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Create an instance of the PopupMenu
PopupMenu menu = new PopupMenu(MainActivity.this, listItemView);
// Inflate the menu using a menu layout file
menu.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// Do something here if correct MenuItem selected
return true;
}
});
}
}

Can't create "Share" menu in popup menu on Android

I have an android app that has a gridview in it. The gridview items contain among other things, a button to show context sensitive menus. So, I implemented a popup menu that comes up when they touch the button in the gridview item.
This menu contains 3 items:
Edit Item
Delete Item
Share Item
I have successfully implemented the edit and delete menu items. The problem is with the "Share Item" menu item. It is a ShareActionProvider. I previously implemented these menu choices as an ActionMode (menu items across the top). But now that the menu is a popup, I'm not sure how to implement the "Share Item" menu option.
Here is my popup_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:id="#+id/group_edit_mode">
<item
android:id="#+id/MenuItemEdit"
android:title="#string/item_option_edit"
app:showAsAction="withText|ifRoom" />
<item
android:id="#+id/MenuItemDelete"
android:title="#string/delete"
app:showAsAction="withText|ifRoom" />
<item
android:id="#+id/MenuItemShare"
android:title="#string/share"
app:showAsAction="ifRoom"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
</group>
</menu>
Here is the popup menu code:
PopupMenu popupMenu = new PopupMenu(MINMainActivity.getSharedInstance(), optionButton);
MenuInflater inflater = popupMenu.getMenuInflater();
inflater.inflate(R.menu.gridview_edit_menu_single_item, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
{
#Override
public boolean onMenuItemClick(MenuItem item)
{
boolean choiceHandled = false;
int itemID = item.getItemId();
switch (itemID)
{
case R.id.MenuItemEdit:
MINPageTypeGridFragment.launchAlbumItemDetails(mFragment, albumItem, mPageItem.pageConfigFileName);
mFragment.currentMode = MINPageTypeGridFragment.MODE_STANDARD;
choiceHandled = true;
break;
case R.id.MenuItemDelete:
MINPageTypeGridFragment.deleteItem(mFragment, mAlbum, albumItem);
mFragment.currentMode = MINPageTypeGridFragment.MODE_STANDARD;
choiceHandled = true;
break;
case R.id.MenuItemShare:
choiceHandled = true;
mFragment.currentMode = MINPageTypeGridFragment.MODE_STANDARD;
break;
}
return choiceHandled;
}
});
popupMenu.show();
This was WAY overthought. I just kept it as a button and created a chooser.
public void onShareClick(MINAlbumItem albumItem)
{
List<MINAlbumItem> albumItemsArray = new ArrayList<MINAlbumItem>();
albumItemsArray.add(albumItem);
// Creates intent and loads data from items array
Intent intent = mFragment.Share(albumItemsArray);
MINMainActivity.getSharedInstance().startActivity(Intent.createChooser(intent, MINMainActivity.getSharedInstance().getResources().getString(R.string.send_to)));
}

Add MenuItem to NavigationView programmatically - item not checked

I've added items to NavigationView programmatically:
**HERE ADD ITEMS**
Menu rightMenu = mRightDrawerView.getMenu();
for (DataParking dataParking : dataParkingList) {
MenuItem menuItem = rightMenu.add(dataParking.getTimeParking());
}
**HERE ADD CLICK LISTENER**
mRightDrawerView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Select menu
menuItem.setChecked(true);
// Closing left_drawer on item click
mDrawerLayout.closeDrawer(mRightDrawerView);
return false;
}
});
Items in navigation drawer are correctly clickable, but the selection is not persistent. If I add the same items via XML all works well.
When you are adding an item programmatically, the item's checkable flag is not set. You should just add this line:
menuItem.setCheckable(true);
after adding an item to menu.
As #Oncky answered, you can just setCheckable on your menuItem like this:
Menu rightMenu = mRightDrawerView.getMenu();
for (DataParking dataParking : dataParkingList) {
MenuItem menuItem = rightMenu.add(dataParking.getTimeParking()).setCheckable(true);
}

Android: Standalone Menubar - onPrepareOptionsMenu?

I have an activity which contains an actionbar at the top and a stand alone toolbar at the bottom. I want to enable/disable an item in this toolbar depending on the value of some variable. Note, that this is inside an fragment.
If I have a normal action bar menu, I can do this in the onPrepareOptionsMenu(Menu menu) method. But this method is not called for the toolbar, nor could I distinguish which toolbar, if it would be called.
How can I prepare the toolbar and its menuitems?
This is my toolbar xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/item_medizinische_daten"
android:title="#string/medizinische_daten"
app:showAsAction="always"></item>
</menu>
This is my code:
toolbarBottom = (Toolbar) getActivity().findViewById(R.id.toolbar_bottom);
toolbarBottom.inflateMenu(R.menu.menu_toolbar_medizinische_daten);
toolbarBottom.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.item_medizinische_daten:
Toast.makeText(getActivity(), "Medizinische Daten clicked", Toast.LENGTH_LONG).show();
break;
default:
}
return true;
}
});
The Toolbar widget has a getMenu() method which you could use to retrieve the Menu that you inflate on it. You could then use that Menu reference and through either findItem() or getItem() find its children and change them.

Categories

Resources