I have an action bar which contains an item shuffle_action.
I have used below case in the onOptionsItemSelected(MenuItem item) function.
switch (item.getItemId()){
case R.id.action_shuffle:
if(MusicService.shuffle) {
item.setChecked(false);
Toast.makeText(this,String.valueOf(item.isChecked()),
Toast.LENGTH_SHORT).show();// returns false
musicService.clearShuffle();
}
else {
item.setChecked(true);
Toast.makeText(this,String.valueOf(item.isChecked()),
Toast.LENGTH_SHORT).show();// returns true
}
musicService.setShuffle();
break;
}
Now this thing works perfectly as i want it to work.
<item
android:id="#+id/action_shuffle"
android:icon="#drawable/shuffle_drawable"
android:title="Shuffle"
app:showAsAction="ifRoom"
android:checkable="true"
android:checked="false"
/>
shuffle_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/shuffle_pressed"/>
<item
android:state_checked="false"
android:drawable="#drawable/ic_shuffle_black_18dp"/>
</selector>
The thing is that when the state changes the drawable won't change.Why is this happening?
Related
I have a working app with an overflow menu. All the code in the menu works, but no checkmarks are being shown after I click on a single-clickable, grouped menu item.
Am I doing something fundamentally wrong? I thought that this displaying of the checkmark was automatic to Android and that the system would do this for me. Android knows it is in a group, it knows that only one can be selected, and it knows which one I selected! So..... Android should know how to display the checkmarks.
Code
XML
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Calculator">
<group
android:checkableBehavior="single"
android:visible="true">
<item
android:id="#+id/ui_simple"
android:orderInCategory="100"
app:showAsAction="ifRoom|withText"
android:title="Regular"
android:checkable="true"/>
<item
android:id="#+id/ui_doge"
android:orderInCategory="100"
app:showAsAction="ifRoom|withText"
android:title="Doge"
android:checkable="true"/>
<item
android:id="#+id/ui_static"
android:orderInCategory="100"
app:showAsAction="ifRoom|withText"
android:title="Static"
android:checkable="true"/>
</group>
<item android:title="Display Mode"
android:orderInCategory="101" >
<menu>
<group android:checkableBehavior="single" android:visible="true" >
<item
android:id="#+id/mode_sign"
android:orderInCategory="100"
app:showAsAction="collapseActionView"
android:title="Sign Form"
android:checkable="true"/>
<item
android:id="#+id/mode_noun"
android:orderInCategory="100"
app:showAsAction="collapseActionView"
android:title="Noun Form"
android:checkable="true"/>
<item
android:id="#+id/mode_verb"
android:orderInCategory="100"
app:showAsAction="collapseActionView"
android:title="Verb Form"
android:checkable="true"/>
</group>
</menu>
</item>
</menu>
UI
Note: I have tried switching all the breaks to return true, but nothing happens.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.ui_simple :
startActivity(new Intent(this, Calculator.class));
break;
case R.id.ui_doge :
startActivity(new Intent(this, CalculatorDoge.class));
break;
case R.id.ui_static :
startActivity(new Intent(this, CalculatorStatic.class));
break;
case R.id.mode_sign : display = BinaryOperation.Display.SIGN; break;
case R.id.mode_verb : display = BinaryOperation.Display.VERB; break;
case R.id.mode_noun : display = BinaryOperation.Display.NOUN; break;
}
return super.onOptionsItemSelected(item);
}
While #Elltz provides a valuable solution to a problem in the code, there are a total of 2 issues in the code.
Problem 1
Do not set a checkable XML attribute in both the Menu Group and the individual MenuItems.
since in the XML there is <group android:checkableBehavior="single" it shows that radio buttons are desired; therefore, no item within the group should have android:checkable="true"
<group
android:checkableBehavior="single" <!-- ONLY HERE -->
android:visible="true" >
<item
android:id="#+id/mode_sign"
android:orderInCategory="100"
app:showAsAction="collapseActionView"
android:title="Sign Form" />
<item
android:id="#+id/mode_noun"
android:orderInCategory="100"
app:showAsAction="collapseActionView"
android:title="Noun Form"/>
<item
android:id="#+id/mode_verb"
android:orderInCategory="100"
app:showAsAction="collapseActionView"
android:title="Verb Form"/>
</group>
Problem 2
Again, #Elltz provides a good solution; however, it is slightly more complex than what it needs to be.
For Single Selection Only
switch (item.getItemId()) {
case R.id.ui_simple : startActivity(new Intent(this, Calculator.class)); return true;
case R.id.ui_doge : startActivity(new Intent(this, CalculatorDoge.class)); return true;
case R.id.ui_static : startActivity(new Intent(this, CalculatorStatic.class)); return true;
// Single Selection - Radio Buttons
case R.id.mode_sign :
item.setChecked(true); // ONLY THIS....HERE
display = BinaryOperation.Display.SIGN;
return true;
case R.id.mode_verb :
item.setChecked(true); // HERE
display = BinaryOperation.Display.VERB;
return true;
case R.id.mode_noun :
item.setChecked(true); // AND HERE
display = BinaryOperation.Display.NOUN;
return true;
default : return super.onOptionsItemSelected(item);
}
For Single OR Multi Selection
// Single OR Multi Select - Radio Buttons or CheckBoxes
switch (item.getItemId()) {
case R.id.ui_simple : startActivity(new Intent(this, Calculator.class)); return true;
case R.id.ui_doge : startActivity(new Intent(this, CalculatorDoge.class)); return true;
case R.id.ui_static : startActivity(new Intent(this, CalculatorStatic.class)); return true;
case R.id.mode_sign :
item.setChecked(!item.isChecked()); // LIKE THIS...HERE
display = BinaryOperation.Display.SIGN;
return true;
case R.id.mode_verb :
item.setChecked(!item.isChecked()); // HERE
display = BinaryOperation.Display.VERB;
return true;
case R.id.mode_noun :
item.setChecked(!item.isChecked()); // AND HERE
display = BinaryOperation.Display.NOUN;
return true;
default : return super.onOptionsItemSelected(item);
}
No
Menu items in the Icon Menu (from the options menu) cannot display a checkbox or radio button. If you choose to make items in the Icon Menu checkable, you must manually indicate the checked state by swapping the icon and/or text each time the state changes.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.ui_simple:
if (item.isChecked()){
item.setChecked(false);
}else{
item.setChecked(true);
}
startActivity(new Intent(this, Calculator.class));
break;
case R.id.ui_doge:
//same goes here and everyone
break;
....
}
}
Hope it helps
I'm trying to highlight menu item title when it is selected in action bar and display its corresponding view in a fragment below. Fragment loading is working good but I'm not able to style menu items when they are clicked.
What I would like to have is something like below mentioned methods-
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// item.setSiblingsStyle(R.style.passive_menu_item);
// item.setStyle(R.style.active_menu_item);
}
Is it possible to style menu title in "onOptionsItemSelected" method? Please help !
You could try to use selector definition:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
<item android:state_pressed="true" android:color="#color/blue_light"/> <!-- pressed -->
<item android:state_enabled="false" android:color="#color/grey_cloud"/> <!-- focused -->
<item android:color="#color/black"/> <!-- default -->
</selector>
I've figured using just text is not a good way. So I decide to add icons and use state of items to toggle by maintaining few variables. Here is an implementation:
private current_selected_menu;
private main_menu;
public void updateMenuState(){
if (main_menu==null){
return;
}
int sz = main_menu.size();
for(int i=0;i<sz;i++){
if(main_menu.getItem(i).getItemId()==current_selected_menu){
main_menu.getItem(i).setEnabled(false);
}
else{
main_menu.getItem(i).setEnabled(true);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sample_menu, menu);
current_selected_menu = menu.getItem(0).getItemId(); // I'm using first item as enabled by default
main_menu = menu;
int sz = menu.size();
for(int i=0;i<sz;i++){
if(menu.getItem(i).getItemId()==current_selected_menu){
menu.getItem(i).setEnabled(false);
}
else{
menu.getItem(i).setEnabled(true);
}
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
// Do something
current_selected_menu = item.getItemId();
updateMenuState();
return true;
case R.id.item2:
// Do something
current_selected_menu = item.getItemId();
updateMenuState();
return true;
default:
// Do Something
return super.onOptionsItemSelected(item);
}
}
As suggested by Xingchen, One can use selectors to define multiple icons. Below is a sample implementation:
icon_selector.xml file in res/drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/icon_passive" android:state_enabled="false"/>
<item android:drawable="#drawable/icon_active" android:state_enabled="true"/>
</selector>
Note: icon_passive.png and icon_active.png are two image files used as icons.
sample_menu.xml file in res/menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu1" android:icon="#drawable/icon_selector" android:title="menu1" android:showAsAction="always|withText" android:visible="true"></item>
<item android:id="#+id/menu2" android:icon="#drawable/icon_selector" android:title="menu2" android:showAsAction="always|withText" android:visible="true"></item>
<item android:id="#+id/menu3" android:icon="#drawable/icon_selector" android:title="menu3" android:showAsAction="always|withText" android:visible="true"></item>
</menu>
I feel there could be better ways than above mentioned. I'll keep this open. Please feel free to suggest better solutions or better practices : )
A the moment I have this options menu
I would like to add to options at the bottom below hybrid map. Here is my code. I have added in where I would like the two other menu options to be but they don't work.
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case R.id.normal_map:
mapType=GoogleMap.MAP_TYPE_NORMAL;
break;
case R.id.satellite_map:
mapType=GoogleMap.MAP_TYPE_SATELLITE;
break;
case R.id.terrain_map:
mapType=GoogleMap.MAP_TYPE_TERRAIN;
break;
case R.id.hybrid_map:
mapType=GoogleMap.MAP_TYPE_HYBRID;
break;
case R.id.games2014:
games2014=true;
break;
case R.id.games_past:
games2014=false;
break;
}
googleMap.setMapType(mapType);
return true;
}
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/map_types"
android:title="Menu"
android:showAsAction="always">
<menu>
<item android:id="#+id/normal_map"
android:title="Mormal map"/>
<item android:id="#+id/satellite_map"
android:title="Satellite map"/>
<item android:id="#+id/terrain_map"
android:title="Terrain map"/>
<item android:id="#+id/hybrid_map"
android:title="Hybrid map"/>
<Item android:id="#+id/games2014"
android:title="2014 Games"/>
<Item android:id="#+id/games_past"
android:title="Previous Games"/>
</menu>
</item>
In your item you declared it as Item which would cause it not to add
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case R.id.normal_map:
mapType=GoogleMap.MAP_TYPE_NORMAL;
break;
case R.id.satellite_map:
mapType=GoogleMap.MAP_TYPE_SATELLITE;
break;
case R.id.terrain_map:
mapType=GoogleMap.MAP_TYPE_TERRAIN;
break;
case R.id.hybrid_map:
mapType=GoogleMap.MAP_TYPE_HYBRID;
break;
case R.id.games2014:
games2014=true;
break;
case R.id.games_past:
games2014=false;
break;
}
googleMap.setMapType(mapType);
return true;
}
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/map_types"
android:title="Menu"
android:showAsAction="always">
<menu>
<item android:id="#+id/normal_map"
android:title="Mormal map"/>
<item android:id="#+id/satellite_map"
android:title="Satellite map"/>
<item android:id="#+id/terrain_map"
android:title="Terrain map"/>
<item android:id="#+id/hybrid_map"
android:title="Hybrid map"/>
<item android:id="#+id/games2014"
android:title="2014 Games"/>
<item android:id="#+id/games_past"
android:title="Previous Games"/>
</menu>
</item>
<Item android:id="#+id/games2014"
android:title="2014 Games"/>
<Item android:id="#+id/games_past"
android:title="Previous Games"/>
Your "I" in "Item" is capital. It should be a lowercase "i" - "item"
I am new to android and stuck at the point where i have to detect clicks on submenus that are defined in XML file
my XML file is :
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/ccard_menu1"
android:title="Select from Profile?"
></item>
<item android:id="#+id/ccard_menu2"
android:title="Add Field"
>
<menu >
<item android:id="#+id/submenu1"
android:title="Add Products"
></item>
<item android:id="#+id/submenu2"
android:title="Add Clients"
></item>
<item android:id="#+id/submenu3"
android:title="Add a Custom Field">s</item>
</menu>
</item>
</menu>
how do i detect clicks on "submenu 1,2,3" in onOptionsItemSelected method?
how do i have to structure the switch case?
I you are looking for something like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.your_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.submenu1:
// do something
return true;
case R.id.submenu2:
//do something else
return true;
// etc..
default:
return super.onOptionsItemSelected(item);
}
}
Please correct me if I am mistaken.
Anyone know how to create the submenu with radio buttons like in the screenshot?
If you want a submenu with checkable radio buttons you should use something like that:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item android:id="#+id/red"
android:title="#string/red" />
<item android:id="#+id/blue"
android:title="#string/blue" />
</group>
</menu>
And then in the code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.red:
return true;
case R.id.blue:
return true;
default:
return super.onOptionsItemSelected(item);
}
}