【问题标题】:PopupMenu Icon doesn't showPopupMenu 图标不显示
【发布时间】:2017-05-26 07:18:30
【问题描述】:

我创建了一个ListView,在每个项目中都有一个PopupMenu。我创建了一个menu layout 并将其用作我的PopupMenu。我的问题是每次单击ListView 项目中的省略号选项时,PopupMenu 都会显示为Text,但Icon 没有出现。

这是我的 xml 菜单:

<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>

然后在我的Adapter 中我的ListView 是这样的:

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;
    }
}

提前感谢您的帮助。

【问题讨论】:

  • 同样,我的图标没有显示出来

标签: android listview popupmenu


【解决方案1】:

我在link 中找到了解决方案并将其应用到我的代码中。

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();
    }

【讨论】:

  • 这种方式可行,但是,如果您在项目中使用 proguard/dexguard,由于使用反射,这可能不适用于发布 APK。
【解决方案2】:

MenuBuilder 是一个隐藏类,但包含显示图标的方法。您将需要使用反射来显示菜单中的图标。尝试在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();
}

【讨论】:

  • 我更新了代码,现在应该可以使用了。这就是在上午 12:40 回答问题时发生的情况。呵呵。
  • 时间不早了(O_O)希望你能早点休息。我尝试了更新的答案,但仍然没有显示图标。我仍然想知道为什么。
  • 我今天早上看了源码。如果您使用的是android.support.v7.widget.PopupMenu,那么我的代码会起作用,因为setOptionalIconsVisibilitypublic。在 AOSP 中,此方法是包私有的,因此我在答案中添加了 method.setAccessible(true);。现在它应该适用于支持库和原生 PopupMenu
  • 是否可以不使用反射显示图标?
【解决方案3】:

在 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()
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多