How to add a menu popup when an action bar item is clicked (see screenshot)? I want the menu item to show an icon.
tHings I have tried:
Setting actionProvider (support lib v7) for the action bar item. In the actionProvider, return null for onCreateActionView. In onPrepareSubMenu, populate the submenu. This works on Android 2.x but not Android 4.0, and for Android 2.x, there is no icon.
In the actionProvider, create a imageview and on clicking, shows a PopupMenu, but popup menu has no icon, when I have specifically used setIcon to show it.
I don't understand why PopupMenu does not show any icon. I followed the "official" code as closely as possible but to no avail.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/widget/ShareActionProvider.java#195
Please help!
Thanks!
Use popUpMenu ->>> Follow>
res/menu/horario.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_MudaDia"
android:titleCondensed="Mudar Dia"
android:title="Mudar Dia"
android:icon="#drawable/ic_menu_popup"
android:showAsAction="always">
</item>
activity.class
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.horario, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_MudaDia:
View vItem = getActivity().findViewById(R.id.menu_MudaDia);
PopupMenu popMenu = new PopupMenu(getActivity(), vItem);
for (int i = 0; i < diaSemana.length; i++)
{
popMenu.getMenu().add(0, i, i, diaSemana[i]);
}
popMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
DIA = diaSemana[item.getItemId()];
atualizaGUI();
return true;
}
});
popMenu.show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
You can try creating a layout with the ImageView and TextView. Inflate that layout inside a PopUpWindow (refer : http://developer.android.com/reference/android/widget/PopupWindow.html).
Use the showAsDropDown(View actionBarIcon) method to show the menu on your actionbar icon click.
I use support library v7 and works well.
- use ActionProvider
I use custom ActionProvider and it works well at 2.x and 4.x ,
code in onPrepareSubMenu
subMenu.clear();
// labels contain list item text.
int len = labels.length;
for(int i = 0; i < len; i++) {
subMenu.add(0, labels[i], i, labels[i])
.setIcon(icons[i])
.setOnMenuItemClickListener(new MineMenuItemClickListener());
}
super.onPrepareSubMenu(subMenu);
- about PopupMenu
PopupMenu don't show icon as default, but you can do your own PopupMenu and set icon display.
Like this man does CustomPopupMenu
The only modify is add mPopup.setForceShowIcon(true);
Related
I have an imageButton in a xml file. Now want to make it a menu button, so that when a user click on the button it should show the drop down menus. But I am not able to figure out what are the possible solution(s).
Can anyone help?
If you're trying to show a drop down menu when clicking an ImageButton (or any other View), try this:
final ImageButton imageButton = // get your ImageButton from the XML here
final PopupMenu dropDownMenu = new PopupMenu(getContext(), imageButton);
final Menu menu = dropDownMenu.getMenu();
// add your items:
menu.add(0, 0, 0, "An item");
menu.add(0, 1, 0, "Another item");
// OR inflate your menu from an XML:
dropDownMenu.getMenuInflater().inflate(R.menu.some_menu, menu);
dropDownMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case 0:
// item ID 0 was clicked
return true;
case 1:
// item ID 1 was clicked
return true;
}
return false;
}
});
imageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dropDownMenu.show();
}
});
// if you want to be able to open the menu by dragging on the button:
imageButton.setOnTouchListener(dropDownMenu.getDragToOpenListener());
When Android Studio asks to import PopupMenu you may see two options:
android.support.v7.widget.PopupMenu this is the best option, it ensures your menu will work in any Android version
android.widget.PopupMenu this one only works on Android 2.1 and up, which is probably fine. However, if new Android versions come with new features in PopupMenu, the first option may also let you use those new features in older Android versions.
I am trying to present a custom action bar while long pressing a textview. My menu has more than 5 items which causes some of the items to be present under the overflow menu.
When I press the overflow icon, the action bar gets destroyed and I am not able to choose any item inside the overflow.
ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.add_rule_menu, menu);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (!mOptionsList.contains(item.getItemId()))
item.setVisible(false);
}
return false;
}
// Clicking on overflow button does not trigger this method at all.
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
// Rest of the code
}
}
public void onDestroyActionMode(ActionMode mode) {}
};
textView.setCustomSelectionActionModeCallback(mActionModeCallback);
I filed an issue about this years ago, which has never been resolved.
A cheesy workaround is to use nested action modes. By this, I mean you have an item in an action mode that finishes the current mode and starts a new one, to provide a "drill-down menu" effect. I use this in my recently-resuscitated RichEditText widget, which offers an action mode for formatting text. I add a "format" item to the default action mode via setCustomSelectionActionModeCallback(). Tapping on "format" opens another action mode that offers options like bold and italic, along with further drill-downs to get to thinks like font changes.
I have a NavigationDrawer and hide/show the OptionsMenu (which is located on the bottom due to a split ActionBar) whenever the drawer gets opened/closed:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!isDrawerOpened) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
return false;
}
I would like to hide the Menu with an animation, (for reference: like the animation used by the system when you call ActionBar.hide() ), however I found no way to access the Layout used for the Menu (so I could get a View object to apply the animation to). It seems there's no public API available to perform this, I wouldn't mind some reflection approach if I knew what to look for. Any suggestions?
UPDATE
looking at this source I finally figured out how to access the View of a split ActionBar using a non-public identifier:
private View getSplitActionBarView() {
Window window = getWindow();
View v = window.getDecorView();
return v.findViewById(getResources().getIdentifier("split_action_bar",
"id", "android"));
}
Now I can create an Animation, set an AnimationListener and call invalidateOptionsMenu() as soon as the Animation ends. There's one problem left: doing this will let an ugly white rectangle at the place where the bottom part of the ActionBar was, this white rectangle will stay there until the Animation is complete. To get rid of it I would need to use <item name="android:windowActionBarOverlay">true</item> in my style XML (or doing the same by code) to display the ActionBar in overlay mode. However this is not what I need.
The question is now: is there any way to apply the overlay mode only to the split ActionBar (= the bottom part of the ActionBar)?
You need to call invalidateOptionsMenu() when the drawer is open/close, like this
public void onDrawerOpened(View view) {
invalidateOptionsMenu();
}
Now, onPrepareOptionsMenu() will be called,where you can hide/show the option menu like this..
#Override
public boolean onPrepareOptionsMenu(Menu menu){
// check if drawer is open
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
for(int index = 0 ; index < menu.size() ; index ++){
MenuItem menuItem = menu.getItem(index);
if(menuItem != null) {
// hide the menu items if the drawer is open
menuItem.setVisible(!drawerOpen);
}
}
return super.onPrepareOptionsMenu(menu);
}
You can hide all the menu or any of the required menu item.
I am using ActionBarSherlock in my application and I want to implement popup menu like the below image, having a logo and respective text.
Please help me to achieve this, any help would be appreciable.
Thanks
Here it is.This is actually done in the app which you posted screenshot for.I think you are familiar with ActionbarSherlok.The button for this dropdown menu will be on actionbar.
public boolean onCreateOptionsMenu(Menu menu) {
// Used to put dark icons on light action bar
SubMenu subMenu1 = menu.addSubMenu("");
subMenu1.add("Item1").setIcon(R.drawable.icon).setOnMenuItemClickListener(
new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
});
MenuItem subMenu1Item = subMenu1.getItem();
subMenu1Item.setIcon(R.drawable.abs__ic_menu_moreoverflow_holo_dark);
subMenu1Item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS
| MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return true;
}
Added PopupMenu in ActionBarSherlock.
so I am trying to get my menu item, that is show on the action bar to behave like a checkable menu option. The firs part works, meaning it is checkable and when I press it, and set in code the setChecked(true) it works. But what does not work is the visual part. There is no change in how a menu item looks on the action bar in checked and unchecked states? I tried using invalidateOptionsMenu() but that does not do the job, and not only that, with that line in my code I can't get out of the checked state?!?
What happens is that invalidate OptionsMenu() seams to unset the checked state and I end up 'looping', or on every press of that menu item I keep going to the unchecked part of the code where it gets checked and with invalidate it gets unchecked I guess...
Here is the code from my XML file for menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/lenslist_menu_add"
android:showAsAction="always"
android:title="#string/add"/>
<item android:id="#+id/lenslist_menu_delete"
android:showAsAction="always"
android:checkable="true"
android:title="#string/delete"/>
</menu>
And here is the java code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.lenslist_menu_add:
return true;
case R.id.lenslist_menu_delete:
if (item.isChecked() == true) {
item.setChecked(false);
deleteMode = false;
lensAdapter.setDeleteMode(false);
} else {
item.setChecked(true);
deleteMode = true;
lensAdapter.setDeleteMode(true);
}
lensAdapter.notifyDataSetChanged();
return true;
}
return super.onOptionsItemSelected(item);
}
Thanks!
Checkable items appear only in submenus or context menus.
You are using them as main menu items, hence it will not work.
SOURCE: Download the API DEMOS, and open the file ApiDemos/res/menu/checkable.xml, you'll see it as a comment on line 13. I don't know why they don't mention this in the Developer Documentation
reference with comment.:
http://alvinalexander.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/res/menu/checkable.xml.shtml
Or just do it yourself
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.item1).setIcon(menu_checked?R.drawable.menu_ico_checked:R.drawable.menu_ico_unchecked);
return super.onPrepareOptionsMenu(menu);
}
and in onOptionsItemSelected do:
....
menu_checked=!menu_checked;
invalidateOptionsMenu();
The best solution is to set the actionLayout of the <Item> to a CheckBox. This solution gives you a native-looking checkbox (with material animations etc), with a font that matches the other items, and it works both as an action and in the submenu.
Create a new layout called action_checkbox.html:
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:checked="false"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Menu"
android:id="#+id/action_item_checkbox"
/>
Set your <Item> like this. Note that you need the Checkable and Checked still in case it is shown in a sub-menu (in which case the actionLayout is ignored.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:id="#+id/menu_action_logging"
android:title="#string/action_logging"
android:orderInCategory="100"
android:showAsAction="always"
android:checkable="true"
android:checked="false"
android:actionLayout="#layout/action_checkbox"
/>
</menu>
In your code, when the menu is created we need to a) set the title of the checkbox to match the menu item title, b) restore the checked state of both the menu checkable, and our extra checkbox, and c) add an onClicked() listener for our extra checkbox. In this code I am persisting the state of the checkbox in a RetainedFragment.
// Set the check state of an actionbar item that has its actionLayout set to a layout
// containing a checkbox with the ID action_item_checkbox.
private void setActionBarCheckboxChecked(MenuItem it, boolean checked)
{
if (it == null)
return;
it.setChecked(checked);
// Since it is shown as an action, and not in the sub-menu we have to manually set the icon too.
CheckBox cb = (CheckBox)it.getActionView().findViewById(R.id.action_item_checkbox);
if (cb != null)
cb.setChecked(checked);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu, inflater);
// Restore the check state e.g. if the device has been rotated.
final MenuItem logItem = menu.findItem(R.id.menu_action_logging);
setActionBarCheckboxChecked(logItem, mRetainedFragment.getLoggingEnabled());
CheckBox cb = (CheckBox)logItem.getActionView().findViewById(R.id.action_item_checkbox);
if (cb != null)
{
// Set the text to match the item.
cb.setText(logItem.getTitle());
// Add the onClickListener because the CheckBox doesn't automatically trigger onOptionsItemSelected.
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onOptionsItemSelected(logItem);
}
});
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_action_logging:
// Toggle the checkbox.
setActionBarCheckboxChecked(item, !item.isChecked());
// Do whatever you want to do when the checkbox is changed.
mRetainedFragment.setLoggingEnabled(item.isChecked());
return true;
default:
break;
}
return false;
}