Android Optionsmenu does not change - android

So my problem is, is that I have a fragment. This fragment is used for creating new objects and editing existing objects.
When I create a new objects, I want to have a save button. And when I edit an object I also want a delete button.
I have two menu layout files. Which are
R.menu.element_actionbar_edit
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_delete"
android:icon="#drawable/ic_action_delete"
android:title="#string/delete"
yourapp:showAsAction="always"/>
<item android:id="#+id/action_save"
android:icon="#drawable/ic_action_done"
android:title="#string/save"
yourapp:showAsAction="always"/>
</menu>
R.menu.element_actionbar_add
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_save"
android:icon="#drawable/ic_action_done"
android:title="#string/save"
yourapp:showAsAction="always"/>
</menu>
Whenever the fragment with all the actions is called, it only onCreateOptionsMenu.
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.element_actionbar_add, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Eventhough I call the R.menu.add layout it still adds two items to the actionbar, before it actually inflates the menu already contains two items.
This fragment is the only place where I actually use a menu right now.
First I had added an if statement in the options create, to check if there was passed an existing object to edit, but in this case it did show the correct layout, but when nothing is passed I should get only the save button?Why does it show the wrong layout, without even specifying it anywhere else?
EDIT:
So it worked!
#Override
public void onPrepareOptionsMenu(Menu menu) {
if(currentObject==null) {
Global.ACTIVITY.getMenuInflater().inflate(R.menu.element_actionbar_add, menu);
}else{
Global.ACTIVITY.getMenuInflater().inflate(R.menu.element_actionbar_edit,menu);
}
super.onPrepareOptionsMenu(menu);
}
At first setting the menu using the onPrepare didn't work either. I had to delete the app from my phone completely, and reinstall it to make it work.

If you want your menus to change dynamically you should not
use onCreateOptionMenu instead use onPrepareOptionMenus
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
if(save){
menu.add(0, ADD, 0, "Save");
}
else{
// add rest
}
return super.onPrepareOptionsMenu(menu);
}
this method is called each time you click your menu button and menu.clear() is must since each time you add a menu.
Kindly share your results after implementing.

Related

Do I need an empty onCreateOptionsMenu for empty menus?

In my app I have some activities without menu items, that use the following override:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.appbar_menu_empty, menu);
return true;
}
This works good. If I remove the override, I get the same effect on Android 5.1, i.e. an action bar with no icons.
So the question is: can I drop the override?
The documentation of Activity.onCreateOptionsMenu states:
The default implementation populates the menu with standard system menu items.
What does that mean? Do I need to expect that Android comes up with some buttons I did not explicitly add?
You can remove OncreateOptionsMenu() if you dont want to have menu items.
If you want to add menu items, edit the menu.xml file in resources/menu directory.
From the docs the method is defined in Activity class as below
Initialize the contents of the Activity's standard options menu. You
should place your menu items in to menu.
This is only called once, the first time the options menu is
displayed. To update the menu every time it is displayed, see
onPrepareOptionsMenu(android.view.Menu).
The default implementation populates the menu with standard system
menu items. These are placed in the android.view.Menu.CATEGORY_SYSTEM
group so that they will be correctly ordered with application-defined
menu items. Deriving classes should always call through to the base
implementation.
You can safely hold on to menu (and any items created from it), making
modifications to it as desired, until the next time
onCreateOptionsMenu() is called.
When you add items to the menu, you can implement the Activity's
onOptionsItemSelected(android.view.MenuItem) method to handle them
there.
Parameters:
menu The options menu in which you place your items. Returns:
You must return true for the menu to be displayed; if you return false it will not be shown.
public boolean onCreateOptionsMenu(Menu menu) {
if (mParent != null) {
return mParent.onCreateOptionsMenu(menu);
}
return true;
}
also check this SO thread out onCreateOptionsMenu() calling super
check the code for Activity class here http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/app/Activity.java#Activity.onCreateOptionsMenu%28android.view.Menu%29
see some sample code here where you need to show option in action bar menu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_act_add_recipe, menu);
super.onCreateOptionsMenu(menu, inflater);
}
/res/menu/menu_act_add_recipe.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_add_image"
android:icon="#drawable/ic_tab_add_image_white"
android:orderInCategory="100"
android:title="#string/action_preview"
app:showAsAction="always" />
<item
android:id="#+id/action_recipe_preview"
android:icon="#drawable/ic_tab_check_white"
android:orderInCategory="100"
android:title="#string/action_preview"
app:showAsAction="always" />

Android - Correct use of invalidateOptionsMenu()

I have been searching a lot on invalidateOptionsMenu() and I know what it does. But I cannot think of any real life example where this method could be useful.
I mean, for instance, let's say we want to add a new MenuItem to our ActionBar, we can simply get the Menu from onCreateOptionsMenu(Menu menu) and use it in any button's action.
Now to my real question, is following the only way of using invalidateOptionsMenu()?
bool _OtherMenu;
protected override void OnCreate (Bundle bundle)
{
_OtherMenu = false;
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate
{
if(_OtherMenu)
_OtherMenu = false;
else
_OtherMenu = true;
InvalidateOptionsMenu ();
};
}
public override bool OnCreateOptionsMenu (IMenu menu)
{
var inflater = this.SupportMenuInflater;
if(_OtherMenu)
inflater.Inflate (Resource.Menu.another_menu, menu);
else
inflater.Inflate (Resource.Menu.main_activity_menu, menu);
return base.OnCreateOptionsMenu (menu);
}
Click the button and a different menu appears. Click the button again and previous menu appears.
P.S. Sorry for the C# syntax.
invalidateOptionsMenu() is used to say Android, that contents of menu have changed, and menu should be redrawn. For example, you click a button which adds another menu item at runtime, or hides menu items group. In this case you should call invalidateOptionsMenu(), so that the system could redraw it on UI. This method is a signal for OS to call onPrepareOptionsMenu(), where you implement necessary menu manipulations.
Furthermore, OnCreateOptionsMenu() is called only once during activity (fragment) creation, thus runtime menu changes cannot be handled by this method.
All can be found in documentation:
After the system calls onCreateOptionsMenu(), it retains an instance
of the Menu you populate and will not call onCreateOptionsMenu() again
unless the menu is invalidated for some reason. However, you should
use onCreateOptionsMenu() only to create the initial menu state and
not to make changes during the activity lifecycle.
If you want to modify the options menu based on events that occur
during the activity lifecycle, you can do so in the
onPrepareOptionsMenu() method. This method passes you the Menu object
as it currently exists so you can modify it, such as add, remove, or
disable items. (Fragments also provide an onPrepareOptionsMenu()
callback.)
On Android 2.3.x and lower, the system calls onPrepareOptionsMenu()
each time the user opens the options menu (presses the Menu button).
On Android 3.0 and higher, the options menu is considered to always be
open when menu items are presented in the action bar. When an event
occurs and you want to perform a menu update, you must call
invalidateOptionsMenu() to request that the system call
onPrepareOptionsMenu().
use this to reload new menu during app lifecycle:
new:
getActivity().invalidateOptionsMenu();
old
ActivityCompat.invalidateOptionsMenu(getActivity());
You need to override method onPrepareOptionsMenu(), write your update code of action menu in same method and if you are using fragment then add setHasOptionsMenu(true); in onCreateView().
Hope it helps you
One use I've found is forcing an order of operations between onResume and onCreateOptionsMenu/onPrepareOptionsMenu. The natural order (as of platform 22 at least) seems to flip flop around, especially when re-orientating your device.
Call invalidateOptionsMenu() in onResume() and you'll guarantee that onPrepareOptionsMenu will be called after onResume (it may additionally be called before). For example, this will allow enabling a menu item based on data retrieved in onResume.
/**
* Set a hint for whether this fragment's menu should be visible. This
* is useful if you know that a fragment has been placed in your view
* hierarchy so that the user can not currently seen it, so any menu items
* it has should also not be shown.
*
* #param menuVisible The default is true, meaning the fragment's menu will
* be shown as usual. If false, the user will not see the menu.
*/
public void setMenuVisibility(boolean menuVisible) {
if (mMenuVisible != menuVisible) {
mMenuVisible = menuVisible;
if (mHasMenu && isAdded() && !isHidden()) {
mHost.onSupportInvalidateOptionsMenu();
}
}
}
XML menu sample:
<?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/action_edit"
android:icon="#drawable/ic_edit"
android:title="Edit Task"
app:showAsAction="always" />
<item
android:id="#+id/action_delete"
android:icon="#drawable/ic_delete"
android:title="Delete Task"
app:showAsAction="always" />
<item
android:id="#+id/action_check"
android:icon="#drawable/ic_check"
android:title="Check Task"
app:showAsAction="always" />
<item
android:id="#+id/action_uncheck"
android:icon="#drawable/ic_undo"
android:title="Uncheck Task"
app:showAsAction="always" />
</menu>
Code inside a sample fragment:
private boolean isMenuItemChecked;
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setMenuVisibility(false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.my_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
try {
menu.findItem(R.id.action_check).setVisible(!isMenuItemChecked);
menu.findItem(R.id.action_uncheck).setVisible(isMenuItemChecked);
}
catch(Exception e) {
Log.e(TAG, "onPrepareOptionsMenu error");
}
}
public void loadUi(boolean isMenuItemChecked) {
this.isMenuItemChecked = isMenuItemChecked;
setMenuVisibility(true);
}
Put the initial state of the menu in onCreateOptionsMenu(...).
Use the invalidateOptionsMenu() to force onCreateOptionsMenu(...) and onPrepareOptionsMenu(...).
In onPrepareOptionsMenu(...), call menu.clear() to remove all items from the menu.
Still in onPrepareOptionsMenu(...) place your dynamic menu changes after the clear.
Edit: Here is a better answer to the question.
A good use for invalidateOptionsMenu() is when we have a ListView and Delete All MenuItem so when the ListView is empty we should use invalidateOptionsMenu() to remove the Delete All MenuItem.
Here is a question related to this answer: Question.
It's old, but hope this helps some one out in the future.
One use I found on real life scenario:
Assume you've a list of items that are stored into database, and you've 2 activities:
DisplayActivity: which displayed these objects after getting them
from database.
EditActivity: used to edit an existing item & save that into database.
You decided to have a couple of options to go from DisplayActivity to EditActivity:
First: To add a brand-new item into database.
Second: To edit an existing item.
In order not to repeat yourself by duplicating code, you decided to use EditActivity for both purposes.
And so, you want to customize Options Menu according to each purpose. For this case you'd build a default options menu using onCreateOptionsMenu(), and leave it as-is when it's time to edit an existing item; and invalidateOptionsMenu() it when it's time to create new items; and in this case onPrepareOptionsMenu() is auto triggered for customizing your menu.
For instance the Options menu can have a delete option for editing an existing item, and this should be hidden when adding a new item.
From fragment call getActivity().invalidateOptionsMenu();.

How to set visibility for an actionbar menu group?

UPDATE
Originally I was using ActionBarSherlock I have since created a brand new project using a native android action bar just to test this and I am still getting the same problem.
I am successfully showing/hiding items but not groups. I am rapidly coming to the conclusion that there is a bug in the ActionBar and it is not possible to programmatically set the visibility of a group
END of UPDATE
Given the following menu When accessing the Group I get a null pointer exception
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_settings"
android:title="#string/settings"
android:orderInCategory="100"
android:showAsAction="never"/>
<group android:id="#+id/mnu_text_group"
android:visible="false">
<item android:id="#+id/mnu_text_type"
android:enabled="true"
android:visible="true"
android:icon="#drawable/ic_action_text_icon"
android:showAsAction="always">
</item>
<item android:id="#+id/text_color"
android:enabled="true"
android:visible="true"
android:showAsAction="always"
android:icon="#drawable/ic_action_color_line">
</item>
</group>
<item android:id="#+id/mnu_images"
...
In the onPrepareOptionsMenu of the relevant activity I have
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem mnuTextGroup = menu.findItem(R.id.mnu_text_group);
mnuImage.setEnabled(mEnableImageMenu);
mnuTextGroup.setVisible(false);
...
The call to mnuTextGroup.setVisible(false); raises a null pointer exception
However, by changing the find method to find an item within the group works fine e.g. MenuItem mnuTextGroup = menu.findItem(R.id.mnu_text_type);but obviously this works just for the specific item. I know groups are designed for exactly this purpose, to be able to set the visibility of and enable/disable all items within the group but I have been unable to find a way to do this programatically.
Finally found the solution
I needed to use the setGroupVisible() method of the menu object passed into the onPrepareOptionsMenu() method
This is what worked for me
Instead of
MenuItem mnuTextGroup = menu.findItem(R.id.mnu_text_group);
mnuImage.setEnabled(mEnableImageMenu);
mnuTextGroup.setVisible(false);
This is what I needed
menu.setGroupVisible(R.id.mnu_text_group, false);
Simple and one line
navigationView.getMenu().setGroupVisible(R.id.groupstaff, false);
Use In Activity Where You Want to Hide
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.main_itemlist, menu);
boolean isdown = false;
menu.findItem(R.id.addwork).setVisible(isdown);
MenuItem mnuTextGroup = menu.findItem(R.id.mnu_text_group);
mnuTextGroup.setVisible(isdown);
return true;
}
altering the options menu needs to be done within onPrepareOptionsMenu or else it sometimes doesn't work (not sure exactly why, hopefully someone else can elaborate):
#Override public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
// set visibility of menu items here
return true;
}

Showing option at the bottom of the screen

I am new to this android.In my application when user clicks Menu button ,i want to show 1 option at the bottom of the screen(background should remain as the current screen).Simply i have to say means if user clicks menu button as like pop up window 1 option should come at the
bottom of the screen.And user clicks on that some action should happen..I can t able put some screenshots for this.
----------------------
------------>Consider this is screen
---------------------
------------>here the option should come.
----------------------
Please help me.Thanks in advance.
Menu is generally used to give extra functionality to an application.
To achieve your goal you have to implement menu, which will open when you click menu button of device, like below.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.optionmenu, menu);
return super.onCreateOptionsMenu(menu);
}
R.menu#
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/Color" android:title="Color">
<menu>
<item android:id="#+id/RedColor" android:title="Red"/>
<item android:id="#+id/GreenColor" android:title="Green"/>
</menu>
</item>
</menu>
and if you want to do any action on click of option menu, you have to override onOptionsItemSelected to do action on click of menu option, like below.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
if(item.getItemId()==R.id.RedColor)
{
Toast.makeText(MenuOptionDemoActivity.this,"Red Color Selected" ,1000).show();
}
else if(item.getItemId()==R.id.GreenColor)
{
Toast.makeText(MenuOptionDemoActivity.this, "Green Color Selected", 1000).show();
}
return super.onOptionsItemSelected(item);
}
}
A clear and simple tutorial to implement menu in your app.
That can be done, but the solution is too long for me to post here, so instead follow the link to a tutorial for creating a menu
http://www.androidhive.info/2011/09/how-to-create-android-menus/
Just as a brief overview of the tutorial - You start by overriding the onCreateOptionsMenu method. In this you inflate your menu. Then you override the onItemSelected method, in which you pu a switch to determine which option phase been selected, though in your case it will only be one item. Finally you have to create an XML file which contains all the options for your menu.

How to add my menu button in system bar in Android 3.1?

My pad is SAMSUNG GT-P7510.I want to add a new menu in the system bar.But the menu shows in action bar.Like this:
But now it is like this:
It's in the right of top.
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0,0,1,"OK");
return true;
}
}
my guess is you started off with a pre-honeycomb app and ran it on 3.*+ emulator.
it happens automatically if you use the right layout style/theme.
on eclipse just go to your layout and choose "android 3.0" on the top right corner.
hope it helps.
EDIT:
after you edited your question I understand i got your question wrong.
If I understand correctly you are just trying to show the menu item as a button outside the menu list and that's simple -
on the xml use the "showAsAction" option like so-
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_share"
android:icon="#drawable/ic_menu_share"
android:title="#string/menu_share"
android:alphabeticShortcut='o'
android:showAsAction="ifRoom|withText" />
</menu>
inflating it with
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.list_options_menu, menu);
or by code:
MenuItem item = menu.add("OK");
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Please remove targetSdkVersion from manifest.xml file..
like from this format:
make it like:
Thanks,
Ram

Categories

Resources