versiones sandwich nougat lollipop jelly honeycomb froyo descargar cream caracteristicas bean android android-3.0-honeycomb

android - nougat - ice cream sandwich



¿Es posible mostrar íconos en un PopupMenu? (11)

Me gusta mucho el nuevo PopupMenu que obtuvimos en 3.0, pero simplemente no puedo mostrar ningún icono junto a los elementos del menú. Estoy inflando el menú del .xml a continuación:

<item android:id="@+id/menu_delete_product" android:icon="@drawable/sym_action_add" android:title="delete" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/menu_modify_product" android:icon="@drawable/sym_action_add" android:title="modify" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/menu_product_details" android:icon="@drawable/sym_action_add" android:title="details" android:showAsAction="ifRoom|withText" />

Con este código:

image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { PopupMenu pop = new PopupMenu(getActivity(), v); pop.getMenuInflater().inflate(R.menu.shelves_details_menu, pop.getMenu()); pop.show(); } });

No puedo hacer que aparezcan los íconos, ¿me estoy perdiendo algo?


Algunas de las soluciones anteriores funcionarán con el hack de reflexión,

Simplemente compartiendo esto: recientemente me encontré con los mismos problemas, pero también quería crear algo más personalizado (agregando una vista personalizada en el menú), así que creé la siguiente lib.

https://github.com/shehabic/Droppy


Contribución a la solución proporcionada por Gaelan Bolger. Utilice este código si obtiene una "IllegalAccessException: acceso al campo no permitido".

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(); } prepareMenu(popup.getMenu()); popup.show();

texto


En la línea de usar la reflexión y sin la necesidad de usar MenuPopupHelper , puede agregar

if (popup.getMenu() instanceof MenuBuilder) { //noinspection RestrictedApi ((MenuBuilder) popup.getMenu()).setOptionalIconsVisible(true); }

antes de inflar el menú


Encontré una solución nativa para esto, usando MenuPopupHelper.setForceShowIcon(true) .

private void createMenu(int menuRes, View anchor, MenuBuilder.Callback callback) { Context context = anchor.getContext(); NavigationMenu navigationMenu = new NavigationMenu(context); navigationMenu.setCallback(callback); SupportMenuInflater supportMenuInflater = new SupportMenuInflater(context); supportMenuInflater.inflate(menuRes, navigationMenu); MenuPopupHelper menuPopupHelper = new MenuPopupHelper(context, navigationMenu, anchor); menuPopupHelper.setForceShowIcon(true); menuPopupHelper.show(); }

Uso

private void initMenu(View view) { view.findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { createMenu(R.menu.help_menu, view, new MenuBuilder.Callback() { @Override public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { switch (item.getItemId()) { case R.id.id1: // Do something break; case R.id.id2: // Do something break; case R.id.id3: // Do something break; } return true; } @Override public void onMenuModeChange(MenuBuilder menu) { } }); } }); }


La forma más fácil que encontré es usar MenuBuilder y MenuPopupHelper .

MenuBuilder menuBuilder =new MenuBuilder(this); MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.menu, menuBuilder); MenuPopupHelper optionsMenu = new MenuPopupHelper(this, menuBuilder, view); optionsMenu.setForceShowIcon(true); // Set Item Click Listener menuBuilder.setCallback(new MenuBuilder.Callback() { @Override public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { switch (item.getItemId()) { case R.id.opt1: // Handle option1 Click return true; case R.id.opt2: // Handle option2 Click return true; default: return false; } } @Override public void onMenuModeChange(MenuBuilder menu) {} }); // Display the menu optionsMenu.show();

menu.xml

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/opt1" android:icon="@mipmap/ic_launcher" android:title="option 1" /> <item android:id="@+id/opt2" android:icon="@mipmap/ic_launcher" android:title="option 2" /> </menu>


Podemos usar el modelo de submenú. Por lo tanto, no es necesario escribir el método para mostrar el menú emergente, se mostrará automáticamente. Echar un vistazo:

menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_more" android:icon="@android:drawable/ic_menu_more" android:orderInCategory="1" android:showAsAction="always" android:title="More"> <menu> <item android:id="@+id/action_one" android:icon="@android:drawable/ic_popup_sync" android:title="Sync"/> <item android:id="@+id/action_two" android:icon="@android:drawable/ic_dialog_info" android:title="About"/> </menu> </item> </menu>

en MainActivity.java

@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }

El resultado es:



Pude mostrar los iconos usando la reflexión. Puede que no sea la solución más elegante, pero funciona.

try { Class<?> classPopupMenu = Class.forName(popupMenu .getClass().getName()); Field mPopup = classPopupMenu.getDeclaredField("mPopup"); mPopup.setAccessible(true); Object menuPopupHelper = mPopup.get(popupMenu); Class<?> classPopupHelper = Class.forName(menuPopupHelper .getClass().getName()); Method setForceIcons = classPopupHelper.getMethod( "setForceShowIcon", boolean.class); setForceIcons.invoke(menuPopupHelper, true); } catch (Exception e) { e.printStackTrace(); }


Si estás dispuesto a ser un poco aventurero, mira el código fuente de Google para PopupMenu. Crea tu propia clase, es decir, MyPopupMenu, que es lo mismo que la clase PopupMenu de Google, pero haz un ligero cambio.

En el constructor de PopupMenu:

public MyPopupMenu(Context context, View anchor) { // TODO Theme? mContext = context; mMenu = new MenuBuilder(context); mMenu.setCallback(this); mAnchor = anchor; mPopup = new MenuPopupHelper(context, mMenu, anchor); mPopup.setCallback(this); mPopup.setForceShowIcon(true); //ADD THIS LINE }

use el método setForceShowIcon para forzarlo a mostrar el ícono. También puede exponer un método público para establecer este indicador también según sus necesidades.


Solo agrega esta etiqueta adentro

aplicación: showAsAction = "siempre"

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" app:showAsAction="always"> <item android:id="@+id/menu_delete_product" android:icon="@drawable/sym_action_add" android:title="delete" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/menu_modify_product" android:icon="@drawable/sym_action_add" android:title="modify" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/menu_product_details" android:icon="@drawable/sym_action_add" android:title="details" android:showAsAction="ifRoom|withText" /> </menu>


antes del método de uso popup.show (), crea una instancia de MenuPopupHelper y llama al método setForceShowIcon (true), como este

try { Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup"); mFieldPopup.setAccessible(true); MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu); mPopup.setForceShowIcon(true); } catch (Exception e) { }