问题
I search a lot on net but there is nothing about preventing popup menu from closing.
Whenever i click on checkbox item or any other popup menu item, popup menu dismiss itself. How can i prevent it from dismissing when user check/uncheck checkbox in popup menu.
I'm showing popup menu on actionbar-menu item's click event.
//main_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.worldofjobs.woj.MainActivity" >
<item
android:id="@+id/action_popUpMenu"
android:icon="@drawable/ic_action_overflow"
android:title="@string/main_action_popUpMenu"
app:showAsAction="always"/>
</menu>
//popup_items.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/refresh_item"
android:title="@string/main_refresh"/>
<item
android:id="@+id/checkbox_item"
android:checkable="true"
android:title="Start notification"/>
<item
android:id="@+id/changePasswrod_item"
android:title="@string/main_changePassword"/>
<item
android:id="@+id/deleteAccount_item"
android:title="@string/main_deleteAccount"/>
<item
android:id="@+id/logout_item"
android:title="@string/main_logout"/>
</menu>
/**
* Shows popup menu on click of action bar-menu inflates from
* menu.pop_items-xml
*/
private void showPopup() {
try {
View v = findViewById(R.id.action_popUpMenu);
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(MainActivity.this);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.pop_items, popup.getMenu());
popup.show();
} catch (Exception e) {
Log.e("MainActivity-showPopup:", e.toString());
}
}
/**
* Handles click events of popup menu items
*/
@Override
public boolean onMenuItemClick(MenuItem item) {
super.onMenuItemSelected(1, item);
switch (item.getItemId()) {
case R.id.refresh_item:
refresh();
return true;
case R.id.checkbox_item:
return true;
case R.id.changePasswrod_item:
changePasswordPopup();
return true;
case R.id.deleteAccount_item:
deleteAccount();
return true;
case R.id.logout_item:
session.logout();
finish();
return true;
}
return true;
}
回答1:
Using popupMenu.show()
to immediately re-show the popup menu does not work correctly with checkable menu items when changing their checked states.
Here a method that prevents closing the popup menu in the first place. Make sure that onMenuItemClick
returns false.
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
item.setChecked(!item.isChecked());
// Do other stuff
// Keep the popup menu open
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
item.setActionView(new View(context));
item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return false;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return false;
}
});
return false;
}
});
回答2:
The trick here is to show the menu right after it dismisses.
Below is a sample code snippet:
popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if(item.getItemId()==R.id.search_by_date_checkbox){
item.setChecked(!item.isChecked());
}
//This is the trick here!!!!
popupMenu.show();
return true;
}
});
You can try this trick with your code! This is how I did it. :)
回答3:
Oliver's answer above (https://stackoverflow.com/a/31727213/2423194) gave me a crash, and its message told me to use MenuItemCompat
instead. After some tweaking to this code, it works:
// Keep the popup menu open
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
item.setActionView(new View(getContext()));
MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return false;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return false;
}
});
Thanks Oliver!
回答4:
In your case R.id.checkbox_item
return false;
This will tell the system that the event has not yet been handeled and it will not dimiss the menu. See HERE
回答5:
Try declaring the PopupMenu globally and calling popup.show();
before returning true in onMenuItemClick
function.
回答6:
Got it working by adding popup.show(); on the click of the button and at the end of the click.
final ImageButton layerButton = (ImageButton) findViewById(R.id.layers);
final PopupMenu popup = new PopupMenu(MapsActivity.this, layerButton);
popup.getMenuInflater().inflate(R.menu.toolbar_menu, popup.getMenu());
layerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Here
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
handleClicksOnCheckBoxes(item);
return true;
}
});
//And here
popup.show();
}
});
However, this is not an optimal solution because if the list has so many items that it will be possible to scroll the list, the list will be scrolled to the top when clicking on an item.
来源:https://stackoverflow.com/questions/29726039/how-to-prevent-popup-menu-from-closing-on-checkbox-click