Search code examples
androidandroid-toolbar

Evenly spaced menu items on Toolbar


So I've been trying to implement android.support.v7.widget.Toolbar in my Activity and to make it look similar to the previously supported split ActionBar.

Here's the XML for my Toolbar:

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

Here's the style for the Toolbar I'm using:

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

The style for the Toolbar menu buttons, my initial plan was to calculate the minWidth based on the screen size and then set it for each menu button.

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

And finally, here is what I'm calling in my activity.

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

The problem is that the menu items in the bottom Toolbar are right aligned like this: Right aligned menu items

However I want them to be evenly spaced like this:

Evenly spaced menu items


Solution

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