studio sgoliver personalizar bar actionbar android android-toolbar

android - sgoliver - Elementos de menú espaciados uniformemente en la barra de herramientas



personalizar toolbar android studio (8)

Así que he estado intentando implementar android.support.v7.widget.Toolbar en mi actividad y hacer que se vea similar a la barra de acción dividida previamente admitida.

Aquí está el XML para mi barra de herramientas:

<android.support.v7.widget.Toolbar android:id="@+id/toolbar_btm" android:layout_height="wrap_content" android:layout_width="match_parent" android:minHeight="?attr/actionBarSize" android:background="@color/toolbar_bkgnd" android:layout_alignParentBottom="true" app:theme="@style/ToolBarTheme" />

Aquí está el estilo de la barra de herramientas que estoy usando:

<style name="ToolBarTheme" parent="Theme.AppCompat"> <item name="actionButtonStyle">@style/ActionButtonStyle</item> <item name="android:actionButtonStyle">@style/ActionButtonStyle</item> <item name="android:textColor">@android:color/white</item> </style>

El estilo de los botones del menú de la barra de herramientas, mi plan inicial era calcular el minWidth función del tamaño de la pantalla y luego configurarlo para cada botón del menú.

<style name="ActionButtonStyle" parent="@android:style/Widget.Holo.Light.ActionButton"> <item name="android:minWidth">56dip</item> <item name="android:paddingLeft">0dip</item> <item name="android:paddingRight">0dip</item> </style>

Y finalmente, esto es lo que estoy llamando en mi actividad.

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_btm); toolbarBtm.inflateMenu(R.id.menu);

El problema es que los elementos del menú en la Toolbar inferior están alineados a la derecha de esta manera:

Sin embargo, quiero que estén espaciados uniformemente de esta manera:



Esta solución toma lo mejor de cada una de las soluciones anteriores, gracias a inner_class7, Kuffs & MrEngineer13.
Esta solución distribuye uniformemente los elementos del menú y muestra el texto.

la clase pública EvenlyDistributedToolbar extiende android.support.v7.widget.Toolbar {

private View actionMenuView; public EvenlyDistributedToolbar(Context context) { super(context); setContentInsetsAbsolute(0, 0); } public EvenlyDistributedToolbar(Context context, AttributeSet attrs) { super(context, attrs); setContentInsetsAbsolute(0, 0); } public EvenlyDistributedToolbar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setContentInsetsAbsolute(0, 0); } @Override public void addView(View child, ViewGroup.LayoutParams params) { if (child instanceof ActionMenuView) { actionMenuView = child ; params.width = LayoutParams.MATCH_PARENT; ((ViewGroup)actionMenuView).setOnHierarchyChangeListener(new OnHierarchyChangeListener() { @Override public void onChildViewRemoved(View parent, View child) { } @Override public void onChildViewAdded(View parent, View child) { if (child instanceof ActionMenuItemView) { //Show the menu item text as well as the the icon ActionMenuItemView actionMenuItemView = (ActionMenuItemView) child; // set the layout parameters on each View actionMenuItemView.setExpandedFormat(true); Drawable[] arr = actionMenuItemView.getCompoundDrawables(); if (arr != null && arr.length == 4 && arr[0] != null) { actionMenuItemView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); } else if (arr != null && arr.length == 4 && arr[2] != null) { actionMenuItemView.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); } actionMenuItemView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); actionMenuItemView.setOnLongClickListener(null); } } }); } super.addView(child, params); } /** * Show All items, call after the menu inflated */ public void showAll() { Menu menu = getMenu(); int size = menu.size(); for (int i = 0; i < size; i++) { MenuItem item = menu.getItem(i); // check if app:showAsAction = "ifRoom" if (((MenuItemImpl) item).requestsActionButton()) { item.setShowAsAction(SupportMenuItem.SHOW_AS_ACTION_ALWAYS); } } } } <com.util.EvenlyDistributedToolbar android:layout_width="match_parent" android:layout_height="wrap_content" />


La solución propuesta por public void setupEvenlyDistributedToolbar(){} por kandroidj funciona perfectamente. Sin embargo, para que la solución sea un poco más completa, necesita un OnclickListener personalizado:

adjunto está mi implementación

private void setupOnClickListener4Toolbar(Toolbar toolbar) { Menu bottomMenu = toolbar.getMenu(); for (int i = 0; i < bottomMenu.size(); i++) { bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return onOptionsItemSelected(item); } }); } }


Mi recomendación es seguir las pautas de diseño . Si está utilizando una toolbar , deje los elementos del menu donde están diseñados para ir.

Sin embargo, si desea un espaciado igual, considere usar Tabs

o una barra de navegación inferior

Esta respuesta le dice cómo configurar una barra de navegación inferior.


Mira esto.

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:abc="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" android:layout_height="?attr/actionBarSize" android:layout_width="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/action1" android:background="@color/red_700"/> <ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/action2" android:background="@color/red_200"/> <ImageView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/action3" android:background="@color/red_100"/> </LinearLayout> </android.support.v7.widget.Toolbar>

Reemplaza ImageView con lo que quieras.


Si crea su menú de manera programática en lugar de inflar de los recursos, puede hacer esto:

Utilice la barra de herramientas SplitToolbar como se menciona en otra respuesta. Obtenga una referencia a la barra de herramientas usando FindViewById de manera normal. Si la barra de herramientas no existe en el diseño, el menú funciona como una versión normal no dividida.

import android.content.Context; import android.support.v7.widget.ActionMenuView; import android.support.v7.widget.Toolbar; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; public class SplitToolbar extends Toolbar { public SplitToolbar(Context context) { super(context); } public SplitToolbar(Context context, AttributeSet attrs) { super(context, attrs); } public SplitToolbar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void addView(View child, ViewGroup.LayoutParams params) { if (child instanceof ActionMenuView) { params.width = LayoutParams.MATCH_PARENT; } super.addView(child, params); } }

Luego en su código de creación de menú haga lo siguiente.

@Override public boolean onPrepareOptionsMenu(Menu menu) { if (toolbar != null) { toolbar.setContentInsetsAbsolute(0,0); menu = toolbar.getMenu(); toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { // Call back to the original menu code to handle menu clicks return onOptionsItemSelected(menuItem); } }); } // Now build your menu as normal menu.clear(); MenuItem b = menu.add(0, WHATEVER, 0, R.string.WHATEVER); b.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); b.setIcon(R.drawable.ic_menu_encrypt); // End of normal menu code // Now set the button options. if (toolbar != null) { int size = menu.size(); for (int i = 0; i < size; i++) { MenuItem item = menu.getItem(i); // check if app:showAsAction = "ifRoom" if (((MenuItemImpl) item).requestsActionButton()) { item.setShowAsAction(SupportMenuItem.SHOW_AS_ACTION_ALWAYS); } } } Return true; }


Here''s lo que funcionó * para mí:

EnhancedMenuInflater.java

import android.support.v4.internal.view.SupportMenuItem; import android.support.v7.internal.view.menu.MenuItemImpl; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import here.is.your.R; public class EnhancedMenuInflater { public static void inflate(MenuInflater inflater, Menu menu, boolean forceVisible) { inflater.inflate(R.menu.menu, menu); if (!forceVisible) { return; } int size = menu.size(); for (int i = 0; i < size; i++) { MenuItem item = menu.getItem(i); // check if app:showAsAction = "ifRoom" if (((MenuItemImpl) item).requestsActionButton()) { item.setShowAsAction(SupportMenuItem.SHOW_AS_ACTION_ALWAYS); } } } }

MainActivity.java

@Override public boolean onCreateOptionsMenu(Menu menu) { if (toolbar == null) { EnhancedMenuInflater.inflate(getMenuInflater(), menu, false); } return super.onCreateOptionsMenu(menu); } // somewhere after views have been set. if (toolbar != null) { EnhancedMenuInflater.inflate(getMenuInflater(), toolbar.getMenu(), true); toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return onOptionsItemSelected(item); } }); }

SplitToolbar.java

import android.content.Context; import android.support.v7.widget.ActionMenuView; import android.support.v7.widget.Toolbar; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; public class SplitToolbar extends Toolbar { public SplitToolbar(Context context) { super(context); } public SplitToolbar(Context context, AttributeSet attrs) { super(context, attrs); } public SplitToolbar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void addView(View child, ViewGroup.LayoutParams params) { if (child instanceof ActionMenuView) { params.width = LayoutParams.MATCH_PARENT; } super.addView(child, params); } }

Layout.xml

<here.is.my.SplitToolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"/>

Cuando digo que funcionó, me refiero a que centraba TODO en mi menú, texto e imágenes por igual. Si solo usas íconos para tu menú, se verá genial. Todavía estoy buscando una forma de centrarlos y tener el texto para estar justo al lado de los íconos.


ACTUALIZAR

Google ahora tiene una funcionalidad muy similar inflada de la manera en que los menús se inflan utilizando una nueva llamada de Widget BottomNavigationView

- Respuesta original -

Chicos, esto me tomó algo de tiempo para darme cuenta y aquí va, es un poco pesado, pero funciona.

Lo uso en una Toolbar de Toolbar para mostrar en la parte inferior de la pantalla como el antiguo SplitActionBar ...

OBSERVA los elementos de menú distribuidos uniformemente en su barra de herramientas

No recomendaría el uso de más de 5 o 6 elementos, puede que se llene un poco ...

/** * This method will take however many items you have in your * menu/menu_main.xml and distribute them across your devices screen * evenly using a Toolbar. Enjoy!! */ public void setupEvenlyDistributedToolbar(){ // Use Display metrics to get Screen Dimensions Display display = getWindowManager().getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); display.getMetrics(metrics); // Toolbar mToolbar = (Toolbar) findViewById(R.id.navigationToolbar); // Inflate your menu mToolbar.inflateMenu(R.menu.menu_bottom); // Add 10 spacing on either side of the toolbar mToolbar.setContentInsetsAbsolute(10, 10); // Get the ChildCount of your Toolbar, this should only be 1 int childCount = mToolbar.getChildCount(); // Get the Screen Width in pixels int screenWidth = metrics.widthPixels; // Create the Toolbar Params based on the screenWidth Toolbar.LayoutParams toolbarParams = new Toolbar.LayoutParams(screenWidth, LayoutParams.WRAP_CONTENT); // Loop through the child Items for(int i = 0; i < childCount; i++){ // Get the item at the current index View childView = mToolbar.getChildAt(i); // If its a ViewGroup if(childView instanceof ViewGroup){ // Set its layout params childView.setLayoutParams(toolbarParams); // Get the child count of this view group, and compute the item widths based on this count & screen size int innerChildCount = ((ViewGroup) childView).getChildCount(); int itemWidth = (screenWidth / innerChildCount); // Create layout params for the ActionMenuView ActionMenuView.LayoutParams params = new ActionMenuView.LayoutParams(itemWidth, LayoutParams.WRAP_CONTENT); // Loop through the children for(int j = 0; j < innerChildCount; j++){ View grandChild = ((ViewGroup) childView).getChildAt(j); if(grandChild instanceof ActionMenuItemView){ // set the layout parameters on each View grandChild.setLayoutParams(params); } } } } }