My problem is that I want to change the icon from a MenuItem from Visible to not being Visible, but this ofcourse needs to go via the onOptionsItemSelected. If I call on menu, it gets the MenuItem where is clicked on, while another one needs to be hidden. And I also checked on defining the MenuItem and findViewById, which didn't work because it's no view.
Let me show you a part of my code to make it more clear:
#Override
public boolean onOptionsItemSelected(MenuItem menu) {
switch (menu.getItemId()) {
case R.id.menu_refresh:
// Stuff
case R.id.menu_settings:
(Somehow point to R.id.menu_refresh).setVisible(false);
}
return super.onOptionsItemSelected(menu);
}
Any ideas?
What I read from the docs, there is a special method for this case: onPrepareOptionsMenu(Menu menu).
Prepare the Screen's standard options menu to be displayed. This is called right before the menu is shown, every time it is shown. You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents.
So that makes it more like this:
#Override
public boolean onOptionsItemSelected(MenuItem menu) {
switch (menu.getItemId()) {
case R.id.menu_refresh:
// Stuff
case R.id.menu_settings:
showRefresh = false;
//Stuff
}
return super.onOptionsItemSelected(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.menu_refresh).setVisible(showRefresh);
return super.onPrepareOptionsMenu(menu);
}
If you're doing a 2.3 style menu, you don't change it in onOptionsItemSelected. You do it in onPrepareOptionsMenu the next time the menu is launched (by saving whatever data is appropriate to save).
If you have an actionbar, you'll need to call invalidateOptionsMenu on the activity to reload the menu, and do the disabling in the create function.
I have an issue with the action bar on Android 4.2 with ActionBarSherlock. I have added an action bar menu item and it uses setOnMenuItemClickListener to set the buttons action.
MenuItem mapButton = menu.findItem(R.id.show_map);
mapButton.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
//Button implementation goes here
}
});
This works fine on Android 2.2 up to Android 4.1 however on Android 4.2 onMenuItemClick does not get called at all.
I have tried adding this
//Handles the map and route button in the options bar
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.show_map:
return false;
case R.id.show_route:
return false;
default:
return super.onOptionsItemSelected(item);
}
}
Which does get called on button press but appears to have no effect. I could move the code the button implements into this function but it would require me to make drastic alterations to other parts of the program. Is there some way to get setOnMenuItemClickListener working on Android 4.2?
I have an Activity in a Library that has a menu in it. The menu has all the standard attributes as well as the #Override on onCreateOptionsMenu and onOptionsItemSelected.
In my actual project which imports above library I have another activity that extends teh above activity. For this specific implementation of this program I want to have a different menu on this activity so inside this activities code base add add onCreateOptionsMenu and onOptionsItemSelected with the proper #Override, but i get the menu from the Library, not the override in the library.
What could I be doing wrong?
Base Class:
public class ListItems extends ListActivity {
public static final int LOGOUT = 0;
public static final int HISTORY = 1;
public static final int REFRESH = 2;
#Override
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0, LOGOUT ,0,"Log Out");
menu.add(0,HISTORY,0,"Order History");
menu.add(0,REFRESH,0,"SMS");
return true;
}
#Override
public boolean onOptionsItemSelected (MenuItem item){
TextView textView = (TextView)findViewById(com.imobileminutes.library.R.id.text);
switch (item.getItemId()){
case LOGOUT:
Intent logOut = new Intent(ListItems.this,MainScreen.class);
startActivity(logOut);
finish();
return true;
case HISTORY:
Intent orderHistory = new Intent(this,OrderItems.class);
startActivity(orderHistory);
return true;
case REFRESH:
Intent orderHistory = new Intent(this,OrderItems.class);
startActivity(orderHistory);
return true;
}
return false;
}
}
Override Class
public class ListItems extends com.imobileminutes.library.ListItems {
static final int SMS = 2;
#Override
public boolean onCreateOptionsMenu(Menu menu){
Log.d("onCreateOptionsMenu", "My onCreateOptionsMenu ran");
Toast.makeText(getApplicationContext(), "HEllo Menu Created", Toast.LENGTH_LONG).show();
super.onCreateOptionsMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected (MenuItem item){
Log.d("onCreateOptionsMenu", "My onOptionsItemSelected ran");
Toast.makeText(getApplicationContext(), "HElloonOptionsItemSelected", Toast.LENGTH_LONG).show();
super.onOptionsItemSelected(item);
return false;
}
}
CONCLUSION
It ended up being that my library was calling ListItems.this and CreateAccount.this which was referencing the activities in the library not in the extended classes.
I added an intent for every extended activity type and nwo call that, thus bringing up the extended activity rather than the base activity.
Thanks for the help guys.
Either you didn't copy and paste the code correctly, or part of the problem is in your base class, which provides the same definition for onCreateOptionsMenu as your derived class:
#Override
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0, LOGOUT ,0,"Log Out");
menu.add(0,HISTORY,0,"Order History");
menu.add(0,REFRESH,0,"SMS");
return true;
}
That last line can't be right -- I'm pretty sure the last line of the base class implementation should be: menu.add(0,REFRESH,0,"REFRESH");.
But that last line of onCreateOptionsMenu also needs to be changed in the derived class:
#Override
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0, LOGOUT ,0,"Log Out");
menu.add(0, HISTORY,0,"Order History");
menu.add(0, SMS,0,"SMS"); // Use the correct constant (SMS instead of REFRESH)
return true;
}
EDIT: Also, you can simplify the code a bit, by re-using the superclass implementation for those choices where you're currently just copying the superclass code (LOGOUT and HISTORY):
#Override
public boolean onOptionsItemSelected (MenuItem item){
TextView textView = (TextView)findViewById(com.imobileminutes.library.R.id.text);
// Left this as a 'switch'; you might want to use an 'if' instead.
switch (item.getItemId()){
case SMS:
AppClass.sendSMS("8135551212", "Hello Jason");
return true;
}
return super.onOptionsItemSelected(item);
}
Use the fully qualified name on the import my suspicion is you are referencing the wrong class.
Turns out it was the way I was calling the Activitys. I was calling the Activity directly in the Library rather than calling the overridden one. Since the overriden ones will be dynamic depending on the Apps naming, I ended up using Intents that will search for the callers packagename and append the specific intent onto it.
As soon as I set all that up, my SMS menu item showed.
In my project i have activity with options menu. I override onOptionsItemSelected method and add my handlers to menu items (switch-case block). But in one handler i need access to another menu item, how i can do that? findViewById doesn't work
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.visit:
//how to access another MenuItem from here?
return true;
}
...
When creating your menu items, you could put the MenuItem you want to check in an attribute (i.e. one of the private fields of your class). This way, when you go into your method, you'll be able toacces the other menu item.
I'm used to working in J2ME. I wanted to do something on Android, but I just can't get how to replace the command class in the events Android scenario.
Do you want to add commands and want them appear in a built-in menu? When user selects one of them you want a predefined function to be called? If I understand your question right and your problem is the same as above here is the solution:
Android provides a built-in menu and let you create your own menu options. Just like in J2ME as you create some menu options(commands in J2ME) they appear in menu automatically.(The menu that appears when the user hits the menu key on the handset)
To add menu to your Activity override onCreateOptionsMenu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_ITEM_ID, 0, "First Menu Option");
return true;
}
Then when user selects an item in the menu onMenuItemSelected(int featureId, MenuItem item) callback is invoked. So you can catch your menu option as follows:
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case MENU_ITEM_ID:
yourFunction(); //your function for this particular item
return true;
}
return super.onMenuItemSelected(featureId, item);
}
If there were more items(options) in menu, you would catch them in switch by their ids.
hope that helps