Evenly spaced menu items on Toolbar

Solution 1:

Here's what worked* for me:

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

When I say worked I mean that it centered EVERYTHING in my menu, text and images alike. If you only use icons for your menu then it will look great. I'm still looking for a way to center them and have the text to be right next to the icons.

Solution 2:

UPDATE

Google now has very similar functionality inflated the normal ways menus inflate using a new Widget call BottomNavigationView

-- Original Answer --

Guys this took me some time to figure out and here you go its a little bit of a heavy operation but it works.

I use this on a Toolbar to display across the bottom of the screen like the old SplitActionBar...

BEHOLD the evenly distributed MenuItems across your Toolbar

I would not recommend using more than 5 or 6 items, it may get a little crowded...

/**
 * 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);
                }
            }
        }
    }
}

Solution 3:

Check this out.

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

Replace ImageView with whatever you want.

Solution 4:

Here is a solution I have posted for another similar question, since on my bottom toolbar I wanted equally spaced buttons: android add two toolbars in the same activity