J'ai donc essayé d'implémenter Android.support.v7.widget.Toolbar
dans mon activité et de lui donner un aspect similaire à l'ActionBar divisé précédemment pris en charge.
Voici le XML pour ma barre d'outils:
<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" />
Voici le style de la barre d'outils que j'utilise:
<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>
Le style des boutons de menu de la barre d’outils, mon plan initial était de calculer la valeur minWidth
en fonction de la taille de l’écran, puis de la définir pour chaque bouton de menu.
<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>
Et enfin, voici ce que j'appelle dans mon activité.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_btm);
toolbarBtm.inflateMenu(R.id.menu);
Le problème est que les éléments de menu dans la Toolbar
inférieure sont alignés à droite, comme suit:
Cependant, je veux qu'ils soient régulièrement espacés comme ceci:
Voici ce qui a fonctionné * pour moi:
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"/>
Quand je dis travaillé, je veux dire que tout est centré dans le menu, le texte et les images. Si vous utilisez uniquement des icônes pour votre menu, alors il aura fière allure. Je cherche toujours un moyen de les centrer et d'avoir le texte à côté des icônes.
METTRE &AGRAVE; JOUR
Google a maintenant des fonctionnalités très similaires qui gonflent les manières habituelles de gonfler les menus en utilisant un nouvel appel de widget BottomNavigationView
- Réponse originale -
Les gars, cela m'a pris du temps à comprendre et voilà, c'est une opération un peu lourde mais ça marche.
J'utilise ceci sur une Toolbar
à afficher en bas de l'écran comme l'ancien SplitActionBar
...
VOICI les éléments de menu répartis uniformément sur votre barre d'outils
Je ne recommanderais pas d'utiliser plus de 5 ou 6 éléments, cela peut devenir un peu encombré ...
/**
* 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);
}
}
}
}
}
Regarde ça.
<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>
Remplacez ImageView
par ce que vous voulez.
Cette solution tire le meilleur parti de chacune des solutions ci-dessus, Merci à inner_class7, Kuffs & MrEngineer13.
Cette solution distribue uniformément les éléments de menu et affiche le texte.
public class EvenlyDistributedToolbar étend 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" />
Voici une solution que j’ai posée pour une autre question similaire, car dans ma barre d’outils inférieure, je voulais des boutons équidistants: Android ajoute deux barres d’outils dans la même activité
Ma recommandation est de suivre les directives design . Si vous utilisez une barre d'outils , laissez les éléments menu là où ils sont conçus.
Cependant, si vous voulez un espacement égal, envisagez d'utiliser Tabs
ou une barre de navigation inférieure
Cette réponse indique comment configurer une barre de navigation inférieure.
La solution proposée par public void setupEvenlyDistributedToolbar(){}
par kandroidj fonctionne parfaitement. Cependant, pour rendre la solution un peu plus complète, vous avez besoin d'une OnclickListener
personnalisée:
ci-joint est ma mise en œuvre
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);
}
});
}
}
Si vous créez votre menu par programme plutôt que de le gonfler à partir de ressources, vous pouvez procéder comme suit:
Utilisez la SplitToolbar comme mentionné dans une autre réponse. Obtenez une référence à la barre d'outils en utilisant FindViewById comme d'habitude. Si la barre d'outils n'existe pas dans la présentation, le menu fonctionne comme une version normale non divisée.
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);
}
}
Ensuite, dans votre code de création de menu, procédez comme suit.
@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;
}