How to put all action items on the left, taking as much space as possible, and yet have overflow on the right?

Viewed 1076

Background

Suppose I have a Toolbar, and multiple action items. Some might be customized (example: TextView with image).

What I need to do is to align them all to the left, instead of to the right, yet still have the overflow item on the right side.

I also try to have as much space as possible to the action items.

The problem

None of what I've found works

What I've tried

1.For the alignment, I've found some solutions on StackOverflow, of adding views inside the Toolbar, but this won't work well for some reason, because pressing an item doesn't show the effect on the whole item (as if it's smaller in height).

Other things I tried for this:

  • android:layoutDirection="ltr" - doesn't do anything to the action items
  • android:gravity="left|start" - same

2.For the space issue, none of what I tried work. I tried to remove all things that might add margins or padding.

Here's a sample code to show how I tested both issues :

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context="com.example.user.myapplication.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
        android:layoutDirection="ltr" android:padding="0px" android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:contentInsetEnd="0px" app:contentInsetEndWithActions="0px" app:contentInsetLeft="0px"
        app:contentInsetRight="0px" app:contentInsetStart="0px" app:contentInsetStartWithNavigation="0px"
        app:logo="@null" app:title="@null" app:titleMargin="0px" app:titleTextColor="#757575"
        tools:ignore="UnusedAttribute" tools:title="toolbar"/>

</FrameLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar mainToolbar = findViewById(R.id.toolbar);
        for (int i = 0; i < 10; ++i) {
            final View menuItemView = LayoutInflater.from(this).inflate(R.layout.action_item, mainToolbar, false);
            ImageView imageView = (ImageView) menuItemView.findViewById(android.R.id.icon);
            String text = "item" + i;
            final int itemIconResId = R.drawable.ic_launcher_background;
            imageView.setImageResource(itemIconResId);
            ((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
            final OnClickListener onClickListener = new OnClickListener() {
                @Override
                public void onClick(final View view) {
                    //do something on click
                }
            };
            menuItemView.setOnClickListener(onClickListener);
            final MenuItem menuItem = mainToolbar.getMenu()
                    .add(text).setActionView(menuItemView).setIcon(itemIconResId)
                    .setOnMenuItemClickListener(new OnMenuItemClickListener() {
                        @SuppressLint("MissingPermission")
                        @Override
                        public boolean onMenuItemClick(final MenuItem menuItem) {
                            onClickListener.onClick(menuItemView);
                            return true;
                        }
                    });
            MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_IF_ROOM);

        }
    }
}

action_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content" android:layout_height="match_parent"
    android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true"
    android:focusableInTouchMode="false" android:gravity="center" android:orientation="horizontal">

    <ImageView
        android:id="@android:id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:scaleType="center" tools:src="@android:drawable/sym_def_app_icon"/>

    <TextView
        android:id="@android:id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_marginLeft="6dp" android:layout_marginStart="6dp" android:gravity="center"
        android:textColor="#c2555555" android:textSize="15sp" tools:text="text"/>

</LinearLayout>

This is what I got:

enter image description here

The question

How can I support max space usage of the Toolbar, and also make the action items align to the left?


EDIT: after a bit work, I got the alignment solution to partially work:

activity_main.xml

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent" android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
        android:background="#fff" android:gravity="center_vertical|start"
        android:layoutDirection="ltr" android:padding="0px" android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:contentInsetEnd="0px" app:contentInsetEndWithActions="0px" app:contentInsetLeft="0px"
        app:contentInsetRight="0px" app:contentInsetStart="0px" app:contentInsetStartWithNavigation="0px"
        app:logo="@null" app:title="@null" app:titleMargin="0px" app:titleTextColor="#757575"
        tools:ignore="UnusedAttribute" tools:title="toolbar">

        <android.support.v7.widget.ActionMenuView
            android:id="@+id/amvMenu" android:layout_width="match_parent" android:layout_height="match_parent"/>
    </android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>

In code, the only difference is that I use the menu of ActionMenuView, instead of the Toolbar:

    final ActionMenuView amvMenu = (ActionMenuView) toolbar.findViewById(R.id.amvMenu);
    final Menu menu =amvMenu.getMenu();
    ...
       final MenuItem menuItem = menu.add...

It does put the overflow item on the far right, while the action items are on the left.

However, the effect of pressing doesn't include the whole height of the items, and it seems as if the items take more space than usual. Plus, I still didn't figure out how to use all the possible space there is here:

enter image description here

EDIT:

In order to fix the issue of the pressing effect, all I had to do is to add android:minHeight="?attr/actionBarSize" to the items that are being inflated in the loop.

What's still weird about the pressing effect is that if I add a normal action item (just text/icon, without inflating), it has a tiny ripple effect, and the action item itself take a lot of space compared to what I add.

Another new issue that this has caused, is that clicking on anywhere near the overflow menu will trigger clicking on it.

EDIT:

Yet another issue from this solution, is that there are spaces between items in some cases, such as one in the case that there are only a few items:

enter image description here

So, in short, this solution doesn't work well at all.

2 Answers
Related