checked context menu items don't stay checked - android

I'm new to this forum and to android development itself so my question will probably be a very stupid one and i apologize for this .
I began reading the Dev Guide on developer.android.com and until the part with the context menus everything worked pretty fine.
Now i tried to have a context menu with a submenu that contains some checkable items. So i added the submenu and the items to my menu.xml and some item.setchecked(true) methods to my onContextItemSelected(...) method.
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/info"
android:title="#string/info" />
<item android:title="#string/change">
<menu>
<item android:id="#+id/checkable_item1"
android:checked="true"
android:checkable="true"
android:title="#string/hello"/>
<item android:id="#+id/checkable_item2"
android:checkable="true"
android:title="#string/moin"/>
<item android:id="#+id/checkable_item3"
android:checkable="true"
android:title="#string/aloha"/>
</menu>
</item>
</menu>
part of my .java file
...
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater1 = getMenuInflater();
inflater1.inflate(R.menu.context_menu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case R.id.checkable_item1:
if(item.isChecked()) item.setChecked(false);
else item.setChecked(true);
return true;
case R.id.checkable_item2:
if(item.isChecked()) item.setChecked(false);
else item.setChecked(true);
return true;
case R.id.checkable_item3:
if(item.isChecked()) item.setChecked(false);
else item.setChecked(true);
return true;
default:
return super.onContextItemSelected(item);
}
}
...
Now the problem is that when i open the menu and press one of the checkable items and i can see that the green tick pops up in the little box just before the context menu closes but when i open up the menu again the tick is gone.
Now i don't really know why the tick doesn't stay in the box.
It would be nice if someone could give me hint and tell me what i'm doing wrong.
thanking you in anticipation
jean-claude91

I haven't tried it myself but if I read the description here properly (http://developer.android.com/reference/android/app/Activity.html#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)),
your layout resource will be called every time the menu is created. Since it's "not safe to hold on to a menu after the method returns" , you would need to process the selected item and persist that selection somewhere and then pass the current state of the selectable items into the onCreate with menuInfo, setting checked/unchecked using that info.
If you don't, then the menu will be recreated every time based on your default settings (menu.xml).

Related

Hide action bar 3 dots but display items

I am having an issue where i have 2 items in my action bar (one 'refresh' button and one 'Save' Button, but for some reason they do not show, instead they are nested inside an options menu (3 dots). Would anyone know how to remove the 3 dots menu and display my 2 items? I have tried many things but ultimately I just end up removing all three items. Thanks in advance.
Here is my code
add_event_action.xml (this is my menu xml)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_refresh"
android:showAsAction="always"
android:icon="#drawable/ic_action_refresh"
android:title="Refresh"/>
<item
android:id="#+id/action_save"
android:showAsAction="always"
android:title="#string/save"/>
</menu>
Here is my Java class
public class RandomActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_events_list);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.add_event_action, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// action with ID action_refresh was selected
case R.id.action_refresh:
Toast.makeText(this, "Refresh selected", Toast.LENGTH_SHORT)
.show();
break;
// action with ID action_settings was selected
case R.id.action_save:
Toast.makeText(this, "Save selected", Toast.LENGTH_SHORT)
.show();
break;
default:
break;
}
return true;
}
}
If I understood correctly, you need two menu buttons in your toolbar.
This works for me, place it in your menu.xml:
<item
android:id="#+id/done"
android:title="#string/done"
app:showAsAction="always|withText"/>
Try to use app:showAsAction instead of android:showAsAction
To expand on the other answers somewhat:
When your activity extends from AppCompatActivity, your menu items should use app:showAsAction. When your activity does not (that is, when you're not using the AppCompat support libraries), your menu items should use android:showAsAction.
Documentation: http://tools.android.com/tips/lint-checks
AppCompatResource
Summary: Menu namespace
Priority: 5 / 10
Severity: Error
Category: Correctness
When using the appcompat library, menu resources should refer to the
showAsAction in the app: namespace, not the android: namespace.
Similarly, when not using the appcompat library, you should be using the android:showAsAction attribute.

Create context menu on menu item click

I am in strange situation and I tried to search everywhere but i didn't find anything useful. May be I am following bad design. But here is my situation:
I have AppBar in my app and I have added ActionButton on app bar which we do normally. Now I want to display context menu when user clicks on any of the action button of app bar.
For example: If I have setting button on app bar and if user clicks on that button then I want to display context menu having multiple options.
I know how to create context menu and handle context menu item clicks but i don't know how to transfer control from action button click which lead to display ContextMenu.
Here is my code:
//inflating context menu which will display when user clicks app bar button example like setting
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu_sort, menu);
}
//handling context menu item clicks
#Override
public boolean onContextItemSelected(MenuItem item) {
return super.onContextItemSelected(item);
}
But I am not sure how to handle app bar button clicks which will display context menu:
//Below code is to handle app bar item clicks
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
//handling the menu clicks on menu.xml
switch (id){
//on below action_add click i want to display context menu
case R.id.action_add:
//not sure what to code here
break;
}
Thanks for your help
If i am understanding you right you want to show a submenu?
Then you need to add a menu tag in your R.menu.context_menu_sort.
Like this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/file"
android:title="#string/file" >
<!-- "file" submenu -->
<menu>
<item android:id="#+id/create_new"
android:title="#string/create_new" />
<item android:id="#+id/open"
android:title="#string/open" />
</menu>
</item>
</menu>
For more informations see https://developer.android.com/guide/topics/ui/menus.html

Android Submenu, how to go back to main menu?

I use an xml to for my ContextMenu, which is like :
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/Ordermenu" android:title="Order">
<menu android:id="#+id/OrderBySubMenu">
<item android:id="#+id/OrderByASC" android:title="Order ASC" />
<item android:id="#+id/OrderByDESC" android:title="Order DESC" />
<item android:id="#+id/Cancel" android:title="Cancel" />
</menu>
</item>
<item android:id="#+id/ActionAmenu" android:title="Action A"/>
</menu>
I use following code to display the menu, in my onCreateContextMenu
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.my menu, menu);
I manage option click with following code :
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.Displaymenu:
//do stuff
return true;
case R.id.OrderByASC:
//do stuff
return true;
case R.id.OrderByDESC:
//do stuff
return true;
default :
return(super.onOptionsItemSelected(item));
}
Starting the Context Menu it display Two options:
Order
Action A
Clicking on Order show a submenu :
Order ASC
Order DESC
Cancel
Now, If the user click on cancel (or click on the hardware back button), no action is specified, so it call super.onOptionsItemSelected(item) which go back to my main activity.
How can I manage to go back to the main menu in such case? i.e. diplay the initial :
Order
Action A
I tried this long ago but i think you will have to override onPrepareOptionsMenu as well to get this to work. This is called before it shows, and you will have to put flags here on what items to show for the user.
Try something like this:
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{
// Clear the previous layout
menu.clear();
if(showMainMenu)
{
// Add main menu items..
menu.add(0, R.id.ordermenu, 0, "True");
}
else
{
// Add sub-menu items
menu.add(0, R.id.ordermenuASC, 0, "True");
}
return super.onPrepareOptionsMenu(menu);
}
So when user clicks a main menu item, change the boolean flag a redo the process.
Finally, it worked only by adding :
case R.id.Cancel:
openContextMenu(findViewById(selected_view_id));
return true;
in public boolean onContextItemSelected(MenuItem item)
selected_view_id is stored by
selected_view_id=v.getId();
in onCreateContextMenu
Hope it will help others.

finditem() doesn't find menu, stuck with NullPointerException

I'm stuck while changing some properties on my options menu at onCreateOptionsMenu(). It seems like findItem() returns null, even though I'm pretty sure that the reference to the menu item is correct. My code looks as follows:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_profile, menu);
MenuItem leftie = menu.findItem(R.id.menu_profile);
leftie.setIcon(R.drawable.ic_menu_mapmode);
leftie.setTitle(R.string.back_map);
leftie.setIntent(authIntent);
return true;
}
I really don't know what can be wrong there. Thanks in advance :)
EDIT: I forgot to include the actual problem.
You can mention title and image for that menu item in XML.
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/newsItem"
android:icon="#drawable/news_tab"
android:title="#string/menu_news"/>
<item
android:id="#+id/dryiceItem"
android:icon="#drawable/dryice_tab"
android:title="#string/menu_dryice"/>
</menu>
and can set intent on menuItem like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.newsItem:
// start News activity
//write your intent here.
break;
case R.id.dryiceItem:
//start another activity
//write your intent here.
break;
}
}
I figured it out. The String that references to the menu index, R.menu.activity_profile was the wrong path so it was inflating an empty menu. I changed the string to R.menu.layout and now it works as expected.
System.out.println(menu.size());
MenuItem leftie = menu.findItem(R.id.menu_profile);
System.out.println(leftie);
leftie.setIcon(R.drawable.ic_menu_mapmode);
leftie.setTitle(R.string.back_map);
leftie.setIntent(authIntent);
I've also had this happen when I had a submenu that wasn't properly nested in item tags, like
<item />
<menu>
</menu>
or
<item >
<menu>
</menu>
<item>
Typecast your findItem statement with MenuItem
MenuItem leftie = (MenuItem) menu.findItem(R.id.menu_profile);

onOptionsItemSelected return incorrect ID

(Newbe)
When I click on a menu the above method returns an ID from the first menu, not the one I clicked. If I check for the Title Condensed of the menu it is correct.
int id = item.getItemId(); //returns id of an incorrect menu
String Title = (String) item.getTitleCondensed(); //this returns the correct title.
Any ideas welcome.
I had the same problem. Generated files from the build are not properly updated.
I got the same effect if i reordered the menu items in the xml...build and surprise. Clicking on menu brings other codes than expected.
Do a clean and try again
You should have set each menu item a unique ID in onCreateOptionsMenu and onCreateContextMenu.
For example:
public static final int CONTEXT_MENU_DELETE = Menu.FIRST;
public static final int CONTEXT_MENU_EDIT = CONTEXT_MENU_DELETE + 1;
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.add(0, CONTEXT_MENU_DELETE, 1, R.string.delete);
menu.add(0, CONTEXT_MENU_EDIT, 2, R.string.edit);
}
// And then
#Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case CONTEXT_MENU_DELETE:
// Delete item
break;
case CONTEXT_MENU_EDIT:
// Edit item
break;
}
}
The same is for onCreateOptionsMenu and onOptionsItemSelected. You should have a unique constant for every menu option.
Added:
Didn't you check out this tutorial?
The idea is the same. You should set different ids in menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/new_game"
android:icon="#drawable/ic_new_game"
android:title="#string/new_game" />
<item android:id="#+id/help"
android:icon="#drawable/ic_help"
android:title="#string/help" />
</menu>
And then use those ids in onOptionsItemSelected:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Check out these code blocks from official Android Menu tutorial and compare to your own code. You could also publish your menu.xml, onCreateOptionsMenu and onOptionsItemSelected so it would be easy to figure out your problem.

Categories

Resources