I want to add a submenu inside my OptionsMenu to a menuItem, programatically according to my parameters. I've checked "MenuItem" in android sdk and there is no addSubMenu() method!, although you can find "hasSubMenu()" and "getSubMenu".
Was thinking on doing this in onCreateOptionsMenu:
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem mi = menu.getItem(MYITEMID); // << this is defined in my XML optionsMenu
SubMenu subm = mi.addSubMenu(0,1,0,"Map 1"); // no addSubMenu() method!!!???
....
How do I create a submenu inside a menuitem in code?
Sometimes Android weirdness is really amazing (and amusing..). I solved it this way:
a) Define in XML a submenu placeholder like this:
<item android:visible="true" android:id="#+id/m_area"
android:titleCondensed="Areas"
android:title="Areas"
android:icon="#drawable/restaur"
android:enabled="true">
<menu>
<item android:id="#+id/item1" android:title="Placeholder"></item>
</menu>
</item>
b) Get sub menu item in OnCreateOptionsMenu, clear it and add my submenu items, like this:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mapoptions, menu);
int idx=0;
SubMenu subm = menu.getItem(MYITEM_INDEX).getSubMenu(); // get my MenuItem with placeholder submenu
subm.clear(); // delete place holder
while(true)
{
anarea = m_areas.GetArea(idx); // get a new area, return null if no more areas
if(anarea == null)
break;
subm.add(0, SUBAREASID+idx, idx, anarea.GetName()); // id is idx+ my constant
++idx;
}
}
I know this is an old question, but I just came across this problem myself.
The most straightforward way of doing this, seems to be to simply specify the item itself as a submenu, then add to this item.
E.g.:
menu.add(groupId, MENU_VIEW, Menu.NONE, getText(R.string.menu_view));
menu.add(groupId, MENU_EDIT, Menu.NONE, getText(R.string.menu_edit));
SubMenu sub=menu.addSubMenu(groupId, MENU_SORT, Menu.NONE, getText(R.string.menu_sort));
sub.add(groupId, MENU_SORT_BY_NAME, Menu.NONE, getText(R.string.menu_sort_by_name));
sub.add(groupId, MENU_SORT_BY_ADDRESS, Menu.NONE, getText(R.string.menu_sort_by_address));
:
:
Here's a complete answer which builds on the idea of using a placeholder but uses mostly xml to add the submenu.
If you have a menu like so called main_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="My Menu"
android:id="#+id/my_menu_item">
<!-- A empty SubMenu -->
<menu></menu>
</item>
</menu>
Create another menu sub_menu.xml which will be used in my_menu_item:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="SubMenu One"
android:id="#+id/submenu_one" />
<item android:title="SubMenu Two"
android:id="#+id/submenu_two" />
<item android:title="SubMenu Three"
android:id="#+id/submenu_three" />
</menu>
In your onCreateOptionsMenu:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate your main_menu into the menu
getMenuInflater().inflate(R.menu.main_menu, menu);
// Find the menuItem to add your SubMenu
MenuItem myMenuItem = menu.findItem(R.id.my_menu_item);
// Inflating the sub_menu menu this way, will add its menu items
// to the empty SubMenu you created in the xml
getMenuInflater().inflate(R.menu.sub_menu, myMenuItem.getSubMenu());
}
This solution is nice since the inflater handles most of the work.
The best way to do this is in your xml menu file. You can do this by creating a new menu object inside of an item:
<menu>
<item>
...
<menu>
...
</menu>
...
</item>
</menu>
To provide a comprehensive example of Phil's answer, here is my complete, working XML for a menu with two choices, each of which is a menu with three choices. I intend to add a third menu to the top level ...
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HTMLCode="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/Examine"
android:title="#string/Examine"
HTMLCode:showAsAction="always">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HTMLCode="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/load"
android:title="#string/load"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/findfirst"
android:title="#string/findfirst"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/findnext"
android:title="#string/FindNext"
HTMLCode:showAsAction="ifRoom|withText" />
</menu>
</item>
<item android:id="#+id/Redirect"
android:title="#string/Redirect"
HTMLCode:showAsAction="ifRoom|withText">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HTMLCode="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/getRedirect"
android:title="#string/getRedirect"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/toggleRedirect"
android:title="#string/toggleRedirect"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/copyRedirect"
android:title="#string/copyRedirect"
HTMLCode:showAsAction="ifRoom|withText" />
</menu>
</item>
</menu>
You should consider use a ActionProvider instead.
public class MyActionProvider extends ActionProvider {
private Context mContext;
public MyActionProvider(Context context) {
super(context);
mContext = context;
}
#Override
public View onCreateActionView() {
//LayoutInflater layoutInflater = LayoutInflater.from(mContext);
return null;
}
#Override
public void onPrepareSubMenu(SubMenu subMenu) {
super.onPrepareSubMenu(subMenu);
subMenu.clear();
subMenu.add("menu 1");
subMenu.add("menu 2");
subMenu.add("menu 3");
}
#Override
public boolean hasSubMenu() {
return true;
}
#Override
public boolean onPerformDefaultAction() {
return super.onPerformDefaultAction();
}
}
I would just create the submenu in xml file, and in run time get the submenu from menu object, (using findItem(id) method) and use submenu.setVisible(boolean) to add/remove it on run time.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu1" android:alphabeticShortcut="a"
android:title="Menu No. 1" android:orderInCategory="1" />
<item android:id="#+id/menu2" android:alphabeticShortcut="b"
android:title="Menu No. 2" android:orderInCategory="2">
<menu >
<group android:id="#+id/group2" android:checkableBehavior="single">
<item android:id="#+id/submenu1" android:title="SubMenu No. 1" />
<item android:id="#+id/submenu2" android:title="SubMenu No. 2" />
</group>
</menu>
</item>
Related
In some pages of stackoverflow said that you can get menu goup with menu.findItem(R.id.groupId) but always return null and i want to know how can i get menu group
<?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/fdp_m_group_normal">
<item android:id="#+id/fdp_m_today"
app:actionLayout="#layout/menu_today"
app:showAsAction="always|withText"
android:orderInCategory="100"
android:title="today"/>
<item android:id="#+id/fdp_m_tomorrow"
app:actionLayout="#layout/menu_tomorrow"
app:showAsAction="always|withText"
android:orderInCategory="101"
android:title="tomorrow"/>
<item android:id="#+id/fdp_m_after"
app:actionLayout="#layout/menu_after"
app:showAsAction="always|withText"
android:orderInCategory="102"
android:title="after"/>
</group>
<group android:id="#+id/fdp_m_group_range">
<item android:id="#+id/fdp_m_plus1"
app:actionLayout="#layout/menu_plus1"
app:showAsAction="always|withText"
android:orderInCategory="103"
android:title="+1"/>
<item android:id="#+id/fdp_m_plus2"
app:actionLayout="#layout/menu_plus2"
app:showAsAction="always|withText"
android:orderInCategory="104"
android:title="+2"/>
<item android:id="#+id/fdp_m_plus3"
app:actionLayout="#layout/menu_plus3"
app:showAsAction="always|withText"
android:orderInCategory="105"
android:title="+3"/>
</group>
</menu>
and my java code for accessing menu
#Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fdp_menu, menu);
// Below line always return null
MenuItem mGroupOne = menu.findItem(R.id.fdp_m_group_normal);
super.onCreateOptionsMenu(menu, inflater);
}
Getting group using findItem does return null. I am assuming you only need it for visibility. Try using menu.setGroupVisible(R.id,false);
menu.findItem will return null if there is no item in 'menu' with the id.
So first of all check that 'menu' is the right menu to be looking in, and then check in menu.xml that you have declared an item with the correct id.
I am trying to findview of an overflow icon. After clicking and opening the overflow icon, I tried using in onoptionsitemselected:
View view = getActivity().findViewById(R.id.menu_tag); // null
View view = getActivity().findViewById(R.id.mainMenu); // not null.
<?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/mainMenu"
android:title="#string/text"
android:orderInCategory="101"
android:icon="#drawable/ic_more_vert_white_24dp"
app:showAsAction="always">
<menu>
<item
android:id="#+id/menu_tag"
android:icon="#drawable/tag_32"
app:showAsAction="always|withText"
android:title="#string/tags"/>
<item
android:id="#+id/menu_profile"
android:icon="#drawable/user_32"
app:showAsAction="always|withText"
android:title="#string/profile"/>
<item
android:id="#+id/menu_debug"
android:icon="#drawable/insect_32"
app:showAsAction="always|withText"
android:title="#string/debug"/>
</menu>
</item>
</menu>
It is giving me null but working fine for actionbar items.
You should try to find view in onCreateOptionsMenu method like this :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.optionsMenu = menu;
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menufile, menu);
MenuItem item = menu.findItem(R.id.mainmenu);
return true;
}
I found a solution by setting actionview to imagebutton and then finding the view.
It seems impossible to find any answer on my question/problem regarding af scollable TextSelectionMenu! I have searched the whole Stackoverflow and Google without any succes and I have tried various ideas out.
I have 10 menu items in my custom TextSelectionMenu. Only 6 of them is visible, the rest is of course not, since you can't scroll to the others. Is it possible to implement a Scrollview/HorizontalListview of any sort to be able to scroll to the rest?
My menu_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="#+id/textcolor"
android:icon="#drawable/textcolor"
android:showAsAction="always"
android:visible="true"
android:title="ColorPicker"
tools:ignore="AppCompatResource" />
<item
android:id="#+id/bold"
android:icon="#drawable/bold2"
android:showAsAction="always"
android:visible="true"
android:title="Bold"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/italic"
android:icon="#drawable/italic2"
android:showAsAction="always"
android:title="Italic"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/underline"
android:icon="#drawable/underline2"
android:showAsAction="always"
android:title="Underline"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/stroke"
android:icon="#drawable/strike"
android:showAsAction="always"
android:title="Strikethrough"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/increase"
android:icon="#drawable/increase"
android:showAsAction="always"
android:title="Increase"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/decrease"
android:icon="#drawable/decrease"
android:showAsAction="always"
android:title="Decrease"
tools:ignore="AppCompatResource" />
The CustomTextSelectionMenu class:
public class CustomTextSelectionMenu extends FragmentActivity implements android.view.ActionMode.Callback {
EditText editText = (EditText) findViewById(R.id.edittext);
#Override
public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
menu.removeItem(android.R.id.selectAll);
menu.removeItem(android.R.id.paste);
return true;
}
#Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
return true;
}
#Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
// Just a lot of switch cases inside here...
return true;
}
}
I think, there is no way to scroll the text selection menu.
But you can do is, show the few menu items say 2 or 3 as showAsAction="always" and the rest of the menu items are automatically can be shown in overflow menu.
How I can force menu item to show under overflow icon. I am providing app support from api level 8 and above. for now it is showing as actionview .
My menuLayout is as follows.
//main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_menu_setting"
android:title="#string/menuItemSetting"
app:showAsAction="ifRoom"/>
<item
android:id="#+id/action_signout"
android:title="#string/menuItemLogout"
app:showAsAction="ifRoom"/>
</menu>
in Java class
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
I have tried with other options of showAsAction but none of them worked. Please suggest me how I can show above two menu itme under overflow icon(when i click on over these two will appearer as actionlist.)
layout for custom action bar
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#drawable/header"
android:orientation="vertical" >
<TextView
android:id="#+id/tvActionBarTitle"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="30sp" />
<Button.../>
<!-- your code for button -->
</LinearLayout>
You can call below function in onCreate and define button in this function as I have defined appName text view and its OnClick event
private void createCutomActionBarTitle()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
this.getActionBar().setHomeButtonEnabled(true);
}
this.getActionBar().setDisplayShowCustomEnabled(true);
this.getActionBar().setDisplayShowTitleEnabled(false);
this.getActionBar().setBackgroundDrawable(drawable);
this.getActionBar().setIcon(logo);
LayoutInflater inflator = LayoutInflater.from(this);
View v = inflator.inflate(R.layout.custom_action_bar, null);
((TextView) v.findViewById(R.id.tvActionBarTitle)).setText(Global.ACTIVITY_NAME);
this.getActionBar().setCustomView(v);
}
Hope this will be useful for you :)
But clicking physical button of device will not trigger this button you have to look for it, as I don't have any idea about it
Could you post java code ? Do you have code below in your activity ?
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.menu, menu);;
return super.onCreateOptionsMenu(menu);
}
Edit :
I alway use code like this(when i click action_settings it will show action list contains setting and bar, i think just replace android:title="#string/action_settings" with android:icon)
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="always"
android:title="#string/action_settings">
<menu>
<item
android:enabled="true"
android:visible="true"
android:title="setting"
android:id="#+id/setting">
</item>
<item
android:enabled="true"
android:visible="true"
android:title="B"
android:id="#+id/bar">
</item>
</menu>
</item>
<item
android:id="#+id/action_settings1"
android:orderInCategory="100"
android:showAsAction="always"
android:title="#string/action_settings"/>
</menu>
Hope it helps
How to show icon with option menu.I have tried the following code but my option menu is without image icon.I am using android version 4.0 for developing app.
Java code :
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add("Add Contacts").setIcon(
R.drawable.ic_launcher);
return true;
}
Following is my app's screen shot
I need image to be displayed on the top of "Add Contacts" item.
Override OnPrepareOptionsMenu and add icon from there too
and if its for above 3.0, use android:showAsAction in xml.
eg. android:showAsAction="ifRoom|withText"
I tried the code in two line and it works:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add("Add Contacts");
menu.getItem(0).setIcon(R.drawable.ic_launcher);
return true;
}
You can create a custom menu like this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/add_contacts"
android:icon="#drawable/ic_launcher"
android:title="#string/add_contacts"
/>
</menu>
And then inflate it
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
return true;
}
More on this here:
http://developer.android.com/guide/topics/ui/menus.html#options-menu
you can directly set this into the xml file.
<item android:id="#+id/add_contacts"
android:icon="#android:drawable/plus_icon"
android:title="Add Contacts"/>
You Can try Following this Link.
Check this out and tell me if it worked or not.
Or you can do some thing like this.
Create menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/next"
android:icon="#drawable/ic_next"
android:title="#string/next" />
<item android:id="#+id/previous"
android:icon="#drawable/ic_previous"
android:title="#string/previous" />
<item android:id="#+id/list"
android:icon="#drawable/ic_list"
android:title="#string/list" />
</menu>
And now you will be able to set ICON on menu
Now in CreateOptionMenu
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
And to access that menu.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.next:
Toast.makeText(this, "You have chosen the " + getResources().getString(R.string.next) + " menu option",
Toast.LENGTH_SHORT).show();
return true;
…
default:
return super.onOptionsItemSelected(item);
}
}
To enable Option Menu with Icons:
Wrap the Items with an Item with showAsAction="always" and a Menu:
<?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:title="#string/title_menu"
android:icon="#mipmap/ic_icon_menu"
app:showAsAction="always">
<menu>
<item
android:id="#+id/action1"
android:orderInCategory="100"
android:title="#string/action1"
android:icon="#mipmap/ic_icon_action1"
app:showAsAction="never" />
</menu>
</item>
</menu>
If you use some following attribute in manifest file then it's will be show your icon....
<activity android:name=".ui.CategoryActivity"
android:label="#string/app_name"
**android:theme="#android:style/Theme.NoTitleBar"**></activity>
It's work fine for me...:)
+1 for my own effort...
**must be enter.
Easiest way is to use the #drawable only when setting your menu item.
OR
Simply put the #drawable before the title declaration.
<?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/addToFavorites"
android:icon = "#drawable/ic_favorite_border_white_24dp"
android:title = "Hello"
app:showAsAction="always" />
<item
android:id ="#+id/about"
android:title ="About"
app:showAsAction="never" />
</menu>
the problem is the Androidmanifest.xml.
Remove android:theme="#style/AppTheme" and it will work just fine