I have this simple PopupMenu, but when I click on an item, the item doesn't get checked. Why?
In documentation is:
Menu items in the Icon Menu (from the options menu) cannot display a checkbox or radio button.
Radio button is showing, but only state is not changing...
Java
public void showSortPopup() {
View menuItemView = findViewById(R.id.action_sort);
PopupMenu popup = new PopupMenu(this, menuItemView);
popup.inflate(R.menu.sort);
popup.getMenu().findItem(R.id.sort_def).setChecked(true);
popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.sort_def:
sortOrder = CardCursorContract.CardCursor.DEFAULT_SORT;
mCardsFragment.setSortOrder(sortOrder);
savePref();
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
break;
case R.id.sort_asc:
sortOrder = CardCursorContract.CardCursor.ALPHABETICAL_ASC_SORT;
mCardsFragment.setSortOrder(sortOrder);
savePref();
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
break;
case R.id.sort_desc:
sortOrder = CardCursorContract.CardCursor.ALPHABETICAL_DESC_SORT;
mCardsFragment.setSortOrder(sortOrder);
savePref();
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
break;
default:
break;
}
return false;
}
});
popup.show();
}
XML-File
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item android:id="#+id/sort_def"
android:title="#string/action_sort_def"
android:orderInCategory="1"
android:showAsAction="always" />
<item android:id="#+id/sort_asc"
android:title="#string/action_sort_name"
android:orderInCategory="2"
android:showAsAction="always" />
<item
android:id="#+id/sort_desc"
android:title="#string/action_sort_name_desc"
android:orderInCategory="3"
android:showAsAction="always"/>
</group>
Screen
First of all you can simplify the if checked else statement to
item.setChecked(!item.isChecked())
That way it will always toggle it from true → false and the other way around.
But the problem lies in the fact that you have radiobuttons, what the statement above does is makes the group checked, but what you want is to have the item checked.
To get the behaviour youre looking for you can use item.getSubmMenu() and then use the setChecked method on the particular subMenuItem you want.
For example:
//This will refer to the default, ascending or descending item.
MenuItem subMenuItem = item.getSubMenu().getItem(INDEX_OF_ITEM);
//Check or uncheck it.
subMenuItem.setChecked(!subMenuItem.isChecked());
**Swap These Lines in every case **
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
To
if (item.isChecked()) item.setChecked(true);
else item.setChecked(false);
Related
I would like to be able to keep the check in a menu when selecting an item, but when clicking it and then reopening the menu, the check disappeared.
image of the menu where I select an item
image where I reopen the menu but it is visually as if I had not clicked
here is the menu in java code
public void buttoninit(){
button1 = findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Para agregar un Popup Menu a un Button
PopupMenu popupMenu = new PopupMenu(mostrarActivity.this, button1);
popupMenu.getMenuInflater().inflate(R.menu.menu_filter_pa, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_pa_rut:
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
a = 1;
break;
case R.id.menu_pa_nombre:
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
a = 2;
break;
case R.id.menu_pa_apellido:
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
a = 3;
break;
default:
return false;
}
return true;
}
});
popupMenu.show();
}
});
}
here is the Menu in XML
<group android:checkableBehavior="single">
<item
android:id="#+id/menu_pa_rut"
android:icon="#drawable/ic_filter_list"
android:title="Rut"
app:showAsAction="ifRoom">
</item>
<item
android:id="#+id/menu_pa_nombre"
android:icon="#drawable/ic_filter_list"
android:title="Nombre"
app:showAsAction="ifRoom">
</item>
<item
android:id="#+id/menu_pa_apellido"
android:icon="#drawable/ic_filter_list"
android:title="Apellido"
app:showAsAction="ifRoom">
</item>
</group>
Whenever you will click on button to populate option menu it will reinitialize every time and default value and checks will be applied.
You will have to store click position for the clicked radio button of menu and set checked accordingly.
Or initialize your popup option menu only once by declaring it globally.
you have to move your code out of setOnClickListener just keep popupMenu.show()
and if you want to save your ui state or menu, the better way is to use a live data and viewModel. the live data keeps value even if configuration changes.
I want to show the popup menu on longer click of action bar but exactly below where I click.
toolbar.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
PopupMenu popupMenu = new PopupMenu(HomeActivity.this,toolbar);
popupMenu.getMenuInflater().inflate(R.menu.popup_menu,popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.device_setting:
Toast.makeText(HomeActivity.this, "dev settings", Toast.LENGTH_SHORT).show();
break;
case R.id.app_update:
break;
case R.id.wireless_setting:
break;
case R.id.hide_footer:
break;
}
return true;
}
});
popupMenu.show();
return true;
}
});
and popup_menu.xml is below
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/device_setting"
android:title="Device Setting"></item>
<item android:id="#+id/app_update"
android:title="App Update"></item>
<item android:id="#+id/wireless_setting"
android:title="Wireless Setting"></item>
<item android:id="#+id/hide_footer"
android:title="Full Screen"></item>
</menu>
screen shot is given below.
I want to open popup exactly below where I click (longer click)on ActionBar. Please help
Image Screenshot
According to your requirement, you just need to use the popup window because is very flexible, I prefer this GitHub library
https://github.com/kakajika/RelativePopupWindow
Here, just need to change the position of the window for example
popup.showOnAnchor(toolbar, VerticalPosition.BELOW, HorizontalPosition.LEFT);
I have generated a popUp Menu on button click (as the layout is custom layout so couldn't use onCreateOptionsMenu). Everything is working fine except that the menu looks odd. It has got a shadow behind it which doesn't seem to go well with the app. Is there any way in which I can remove the shadow or make the popup menu look like the menu generated using onCreateOptionsMenu.
Below is the image of my popup Menu
Code: (options_menu.xml)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/option1" android:title="#string/option1"
android:orderInCategory="101" android:showAsAction="always|withText" />
<item android:id="#+id/option2" android:title="#string/option2"
android:orderInCategory="102" android:showAsAction="always|withText" />
</menu>
Activity:
popMenuBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context wrapper = new ContextThemeWrapper(MenuActivity.this, myPopupMenuTextAppearance);
mPopupMenu = new PopupMenu(wrapper, v);
MenuInflater menuInflater = mPopupMenu.getMenuInflater();
menuInflater.inflate(R.menu.options_menu, mPopupMenu.getMenu());
mPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.option1:
startActivity(new Intent(this, XYZ.class));
return true;
case R.id.option2:
someFunction();
return true;
default:
Toast.makeText(this,"You Clicked : " + item.getTitle(),Toast.LENGTH_SHORT).show();
return true;
}
}
});
mPopupMenu.show();
}
});
I saw many posts in SO but couldn't figure out why Overflow icon is not displayed. I am testing on real device Android 4.4 . I get the items displayed on bottom of the screen when options button is pressed . But I need it to appear as 3 dot menu on Top Right like in Gmail App. Pl help. Need something like attached pic of Tubemate app when options button clicked.
Menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!--xmlns:com.app.MainActivity="http://schemas.android.com/apk/res-auto"-->
<item
android:id="#+id/action_search"
android:actionViewClass="android.widget.SearchView"
android:icon="#drawable/icon_search"
android:orderInCategory="1"
android:title="search"
android:showAsAction="never"/>
<item
android:id="#+id/action_end"
android:icon="#drawable/end"
android:menuCategory="container"
android:orderInCategory="2"
android:title="#string/end"
android:showAsAction="never"/>
</menu>
MainActivity:
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{ menu.clear();
this.menu = menu;
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_end:
System.exit(0);
break;
case R.id.action_search:
break;
default:
break;
}
return false;
}
Overflow menu will only appear on devices that don't have physical menu button. In devices with physical menu button it will appear from bottom.
To force overflow menu, put this code inside onCreate:
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class
.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Source
I have read the instructions at the android developers page's in order to get the Checkable menu items:
http://developer.android.com/guide/topics/ui/menus.html
this is my xmlmenu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="all">
<item android:id="#+id/regu"
android:title="#string/Regulatory" />
<item android:id="#+id/warn"
android:title="#string/Warning" />
<item android:id="#+id/temp"
android:title="#string/Temporary" />
<item android:id="#+id/bicy"
android:title="#string/Bicycle" />
</group>
</menu>
And here is my code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.regu:
if (item.isChecked())
{
item.setChecked(false);
currAvailableOptions++;
}
else if(0 != currAvailableOptions)
{
item.setChecked(true);
currAvailableOptions--;
}
return true;
case R.id.warn:
if (item.isChecked())
{
item.setChecked(false);
currAvailableOptions++;
}
else if(0 != currAvailableOptions)
{
item.setChecked(true);
currAvailableOptions--;
}
return true;
case R.id.temp:
if (item.isChecked())
{
item.setChecked(false);
currAvailableOptions++;
}
else if(0 != currAvailableOptions)
{
item.setChecked(true);
currAvailableOptions--;
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.app_menu, menu);
return true;
}
The problem is when I clicked one item, the menu item disappeared. It wouldn't have to stay visible in order to check other menu items?
Any idea?
Greetings
Checkable items appear only in submenus or context menus.
And with submenu they (Google) means:
Submenu A floating list of menu items that appears when the user
touches a menu item that contains a nested menu.
Since your menu items are not submenu items, it will not work
I know this is not a direct answer to your question but please consider the following code instead of your switch, it might help you find the problem.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.regu:
case R.id.warn:
case R.id.temp:
if (item.isChecked())
currAvailableOptions++;
else if(currAvailableOptions != 0)
currAvailableOptions--;
item.setChecked(!item.isChecked());
return true;
default:
return super.onOptionsItemSelected(item);
}
}
What is currAvailableOptions? I looked at the article you linked to and there wasn't anything about that in there. It would seem that all you need to do is check:
if (item.isChecked())
item.setChecked(false);
else
item.setChecked(true);
or at least that's what the tutorial says. Perhaps you should give it another read? Hope this helps.
You should probably add break; statements after each case:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
item.setChecked(!item.isChecked());
break;
case R.id.item2:
item.setChecked(!item.isChecked());
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}