studio iconos how español editar cómo boton bar añadir actionbar android actionbarsherlock android-actionbar android-menu

android - how - Cómo mostrar iconos en el menú Desbordamiento en ActionBar



menu bar en android studio (13)

Sé que no es posible usar la API nativa. ¿Hay alguna solución para implementar ese tipo de vista?


Agregue esto en estilo:

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_settings" app:showAsAction="always" android:icon="@drawable/ic_more_vert_white" android:orderInCategory="100" android:title=""> <menu> <item android:id="@+id/Login" android:icon="@drawable/ic_menu_user_icon" android:showAsAction="collapseActionView|withText" android:title="@string/str_Login" /> <item android:id="@+id/str_WishList" android:icon="@drawable/ic_menu_wish_list_icon" android:showAsAction="collapseActionView" android:title="@string/str_WishList" /> <item android:id="@+id/TrackOrder" android:icon="@drawable/ic_menu_my_order_icon" android:showAsAction="collapseActionView" android:title="@string/str_TrackOrder" /> <item android:id="@+id/Ratetheapp" android:icon="@drawable/ic_menu_rate_the_apps" android:showAsAction="collapseActionView" android:title="@string/str_Ratetheapp" /> <item android:id="@+id/Sharetheapp" android:icon="@drawable/ic_menu_shar_the_apps" android:showAsAction="collapseActionView" android:title="@string/str_Sharetheapp" /> <item android:id="@+id/Contactus" android:icon="@drawable/ic_menu_contact" android:showAsAction="collapseActionView" android:title="@string/str_Contactus" /> <item android:id="@+id/Policies" android:icon="@drawable/ic_menu_policy_icon" android:showAsAction="collapseActionView" android:title="@string/str_Policies" /> </menu> </item> </menu>


En su menú xml, use la siguiente sintaxis para anidar el menú, comenzará a obtener el menú con iconos

<item android:id="@+id/empty" android:icon="@drawable/ic_action_overflow" android:orderInCategory="101" android:showAsAction="always"> <menu> <item android:id="@+id/action_show_ir_list" android:icon="@drawable/ic_menu_friendslist" android:showAsAction="always|withText" android:title="List"/> </menu> </item>


Esto es demasiado tarde, pero alguien puede ayudarme a intentarlo. Obtuve la ayuda de la respuesta de @Desmond Lua que ayuda a quien usa menu.xml

Mi respuesta es para la creación de menú dinámico aquí está mi código:

int ACTION_MENU_ID =1; SpannableStringBuilder builder; @Override public boolean onCreateOptionsMenu(Menu menu) { //this space for icon builder = new SpannableStringBuilder(" " + getString(R.string.your_menu_title)); builder.setSpan(new ImageSpan(this, R.drawable.ic_your_menu_icon), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //dynamic menu added menu.add(Menu.NONE,ACTION_MENU_ID, Menu.NONE, getString(R.string.your_menu_title)) .setShowAsAction(MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT | MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); //set icon in overflow menu menu.findItem(ACTION_MENU_ID).setTitle(builder); }


La mejor solution actual, pero no aceptada solution probablemente funcione en plataformas más antiguas. De todos modos, en el nuevo AppCompat21 +, el método requerido no existe y el método getDeclaredMethod devuelve la excepción NoSuchMethodException .

Así que la solución para mí (probada y funcionando en dispositivos 4.x, 5.x) se basa en el parámetro de fondo de cambio directo. Así que simplemente coloque este código en su clase de Actividad.

@Override public boolean onMenuOpened(int featureId, Menu menu) { // enable visible icons in action bar if (featureId == Window.FEATURE_ACTION_BAR && menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Field field = menu.getClass(). getDeclaredField("mOptionalIconsVisible"); field.setAccessible(true); field.setBoolean(menu, true); } catch (IllegalAccessException | NoSuchFieldException e) { Logger.w(TAG, "onMenuOpened(" + featureId + ", " + menu + ")", e); } } } return super.onMenuOpened(featureId, menu); }


La respuesta de @Simon realmente funciona bien ... pero usted está usando AppCompat Activity ... necesitará usar este código en su lugar ... Porque onMenuOpened () ya no se llama en appcompat-v7: 22.x

@Override protected boolean onPrepareOptionsPanel(View view, Menu menu) { if(menu != null){ if(menu.getClass().getSimpleName().equals("MenuBuilder")){ try{ Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch(NoSuchMethodException e){ Log.e(Constants.DEBUG_LOG, "onMenuOpened", e); } catch(Exception e){ throw new RuntimeException(e); } } } return super.onPrepareOptionsPanel(view, menu); }


La respuesta de Simon fue muy útil para mí, así que quiero compartir cómo la implementé en el método onCreateOptionsMenu como se sugiere:

@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_action_bar, menu); // To show icons in the actionbar''s overflow menu: // http://.com/questions/18374183/how-to-show-icons-in-overflow-menu-in-actionbar //if(featureId == Window.FEATURE_ACTION_BAR && menu != null){ if(menu.getClass().getSimpleName().equals("MenuBuilder")){ try{ Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch(NoSuchMethodException e){ Log.e(TAG, "onMenuOpened", e); } catch(Exception e){ throw new RuntimeException(e); } } //} return super.onCreateOptionsMenu(menu); }


La respuesta publicada anteriormente está bien, en términos generales. Pero básicamente elimina el comportamiento predeterminado del menú Desbordamiento. Cosas como la cantidad de iconos que se pueden mostrar en diferentes tamaños de pantalla y luego caen en el menú de desbordamiento cuando no se pueden mostrar. Al hacer lo anterior, elimina una gran cantidad de funcionalidades importantes.

Un mejor método sería decirle al menú de desbordamiento que muestre los íconos directamente. Puedes hacer esto agregando el siguiente código a tu Actividad.

@Override public boolean onMenuOpened(int featureId, Menu menu) { if(featureId == Window.FEATURE_ACTION_BAR && menu != null){ if(menu.getClass().getSimpleName().equals("MenuBuilder")){ try{ Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch(NoSuchMethodException e){ Log.e(TAG, "onMenuOpened", e); } catch(Exception e){ throw new RuntimeException(e); } } } return super.onMenuOpened(featureId, menu); }


Mi mod simple a la excelente solución de Simon para usar con ActionMode:

@Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { if(menu != null){ if(menu.getClass().getSimpleName().equals("MenuBuilder")){ try{ Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch(NoSuchMethodException e){ Log.e(TAG, "onPrepareActionMode", e); } catch(Exception e){ throw new RuntimeException(e); } } } return true; }


Probé esto en base a las respuestas anteriores y funciona bien, al menos con las versiones más recientes de la biblioteca de soporte (25.1):

@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); if(menu instanceof MenuBuilder){ MenuBuilder m = (MenuBuilder) menu; //noinspection RestrictedApi m.setOptionalIconsVisible(true); } return true; }


Puede hacer uso de SpannableString

public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_tab, menu); MenuItem item = menu.findItem(R.id.action_login); SpannableStringBuilder builder = new SpannableStringBuilder("* Login"); // replace "*" with icon builder.setSpan(new ImageSpan(this, R.drawable.login_icon), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); item.setTitle(builder); }


Según yo, esto solo es posible creando una barra de herramientas personalizada. Debido a que ActionBar por defecto no le da esa característica. Pero puede poner iconos tomando el submenú como elemento secundario de un elemento. Y si tienes una mejor solución que yo ... solo infórmame.

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_settings" android:icon="@drawable/ic_menu_camera" android:showAsAction="never" android:title="@string/action_settings" /> <item android:id="@+id/action_1" android:icon="@drawable/ic_menu_gallery" android:showAsAction="never" android:title="Hello" /> <item android:id="@+id/action_search" android:icon="@android:drawable/ic_search_category_default" android:showAsAction="never" android:title="action_search"> <menu> <item android:id="@+id/version1" android:icon="@android:drawable/ic_dialog_alert" android:showAsAction="never" android:title="Cup cake" /> <item android:id="@+id/version2" android:icon="@drawable/ic_menu_camera" android:showAsAction="never" android:title="Donut" /> <item android:id="@+id/version3" android:icon="@drawable/ic_menu_send" android:showAsAction="never" android:title="Eclair" /> <item android:id="@+id/version4" android:icon="@drawable/ic_menu_gallery" android:showAsAction="never" android:title="Froyo" /> </menu> </item> </menu>


Sobre la base de la respuesta de @Desmond Lua desde above , hice un método estático para usar el dibujo declarado en XML en el menú desplegable y asegurándome de que su color tintado no afecta el estado de dibujo constante.

/** * Updates a menu item in the dropdown to show it''s icon that was declared in XML. * * @param item * the item to update * @param color * the color to tint with */ private static void updateMenuWithIcon(@NonNull final MenuItem item, final int color) { SpannableStringBuilder builder = new SpannableStringBuilder() .append("*") // the * will be replaced with the icon via ImageSpan .append(" ") // This extra space acts as padding. Adjust as you wish .append(item.getTitle()); // Retrieve the icon that was declared in XML and assigned during inflation if (item.getIcon() != null && item.getIcon().getConstantState() != null) { Drawable drawable = item.getIcon().getConstantState().newDrawable(); // Mutate this drawable so the tint only applies here drawable.mutate().setTint(color); // Needs bounds, or else it won''t show up (doesn''t know how big to be) drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); ImageSpan imageSpan = new ImageSpan(drawable); builder.setSpan(imageSpan, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); item.setTitle(builder); } }

Y usarlo se vería algo así cuando se usa en una actividad. Esto podría ser aún más elegante dependiendo de sus necesidades individuales.

@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_activity_provider_connect, menu); int color = ContextCompat.getColor(this, R.color.accent_dark_grey); updateMenuWithIcon(menu.findItem(R.id.email), color); updateMenuWithIcon(menu.findItem(R.id.sms), color); updateMenuWithIcon(menu.findItem(R.id.call), color); return true; }


public void showContextMenuIconVisible(Menu menu){ if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Field field = menu.getClass().getDeclaredField("mOptionalIconsVisible"); field.setAccessible(true); field.setBoolean(menu, true); } catch (Exception ignored) { ignored.printStackTrace(); } } }