Reputation: 3257
I create a ListView
that has an PopupMenu
in each item. I create a menu layout
and use it as my PopupMenu
. My problem is every time I clicked the ellipses option in the item of my ListView
the PopupMenu
is displayed with Text
but the Icon
is not showing up.
Here's my xml menu:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_retry"
android:icon="@drawable/retry"
android:title="@string/retry"
app:showAsAction="always"
/>
<item
android:id="@+id/action_delete"
android:icon="@drawable/delete"
android:title="@string/delete"
app:showAsAction="always"
/>
</menu>
Then in my Adapter
for my ListView
is like this :
public class MyListViewAdapter extends BaseAdapter implements MenuItem.OnMenuItemClickListener {
.....
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = activity.getLayoutInflater();
convertView = inflater.inflate(R.layout.mylistrow, null);
}
final View action = (View) convertView.findViewById(R.id.action);
action.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
showPopup(action, position);
}
});
// ....codes for listview creation....
return convertView;
}
public void showPopup(View v, int listItemPosition) {
PopupMenu popup = new PopupMenu(mContext, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.outbox_menu, popup.getMenu());
popup.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_retry:
return true;
case R.id.action_delete:
return true;
default:
return false;
}
}
Thank you in advance for the help.
Upvotes: 5
Views: 5947
Reputation: 39
Use this instead of android.widget.PopupMenu
androidx.appcompat.widget.PopupMenu popupMenu = new PopupMenu(this,view, Gravity.END);
popupMenu.setForceShowIcon(true);
Upvotes: 3
Reputation: 1789
In Kotlin
val popup = PopupMenu(context, holder.img_menu)
try {
popup.inflate(R.menu.bank_edit_menu)
val fields: Array<Field> = popup.javaClass.declaredFields
for (field in fields) {
if ("mPopup" == field.getName()) {
field.setAccessible(true)
val menuPopupHelper: Any = field.get(popup)
val classPopupHelper =
Class.forName(menuPopupHelper.javaClass.name)
val setForceIcons: Method = classPopupHelper.getMethod(
"setForceShowIcon",
Boolean::class.javaPrimitiveType
)
setForceIcons.invoke(menuPopupHelper, true)
break
}
}
popup.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener{
override fun onMenuItemClick(p0: MenuItem?): Boolean {
Log.e(">>",p0.toString())
return true
}
})
popup.show();
} catch (e: Exception) {
e.printStackTrace()
}
Upvotes: 0
Reputation: 38121
The MenuBuilder
is a hidden class but does contain a method to show icons. You will need to use reflection to show the icons in the menu. Try adding this in showPopop(View, int)
:
PopupMenu popup = new PopupMenu(mContext, v);
try {
Method method = popup.getMenu().getClass().getDeclaredMethod("setOptionalIconsVisible", boolean.class);
method.setAccessible(true);
method.invoke(popup.getMenu(), true);
} catch (Exception e) {
e.printStackTrace();
}
Upvotes: 14
Reputation: 3257
I found a solution in this link and apply it to my code.
PopupMenu popup = new PopupMenu(mContext, view);
try {
Field[] fields = popup.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popup);
Class<?> classPopupHelper = Class.forName(menuPopupHelper.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod("setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
Upvotes: 14