Android 如何将所有动作项放在左边,占据尽可能多的空间,但在右边却有溢出? 背景

Android 如何将所有动作项放在左边,占据尽可能多的空间,但在右边却有溢出? 背景,android,android-toolbar,Android,Android Toolbar,假设我有一个工具栏和多个操作项。有些可能是定制的(例如:带图像的文本视图) 我需要做的是将它们全部向左对齐,而不是向右对齐,但溢出项仍位于右侧 我也尽量给动作项目留出更多的空间 问题 我发现的都不管用 我试过的 1.对于对齐,我在StackOverflow上找到了一些解决方案,即在工具栏中添加视图,但由于某些原因,这不会很好地工作,因为按一个项目不会对整个项目显示效果(好像它的高度较小) 我为此做了其他尝试: android:layoutDirection=“ltr”-对操作项没有任何作用 a

假设我有一个工具栏和多个操作项。有些可能是定制的(例如:带图像的文本视图)

我需要做的是将它们全部向左对齐,而不是向右对齐,但溢出项仍位于右侧

我也尽量给动作项目留出更多的空间

问题 我发现的都不管用

我试过的 1.对于对齐,我在StackOverflow上找到了一些解决方案,即在工具栏中添加视图,但由于某些原因,这不会很好地工作,因为按一个项目不会对整个项目显示效果(好像它的高度较小)

我为此做了其他尝试:

  • android:layoutDirection=“ltr”
    -对操作项没有任何作用
  • android:gravity=“left | start”
    -相同
2.在太空问题上,我尝试过的都没有成功。我试着去除所有可能增加边距或填充的东西

下面是一个示例代码,演示我如何测试这两个问题:

活动\u 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>
<?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>
<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>
<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=".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">
    </android.support.v7.widget.Toolbar>
</FrameLayout>
<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"
    android:paddingLeft="8dp">
    <ImageView
        android:id="@android:id/icon"
        android:layout_width="wrap_content"
        android:layout_height="?attr/actionBarSize"
        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="?attr/actionBarSize"
        android:layout_marginLeft="6dp"
        android:layout_marginStart="6dp"
        android:gravity="center"
        android:textColor="#c2555555"
        android:textSize="15sp"
        tools:text="text" />
</LinearLayout>
它确实将溢出项放在最右边,而操作项放在左边

然而,熨烫的效果并不包括物品的整个高度,而且似乎这些物品比平时占用了更多的空间。另外,我仍然不知道如何使用这里所有可能的空间:

编辑:

为了解决压力效应的问题,我所要做的就是将android:minHeight=“?attr/actionBarSize”添加到循环中正在膨胀的项目中

按压效果仍然很奇怪的是,如果我添加一个普通的动作项目(只是文本/图标,没有膨胀),它会产生一个很小的涟漪效应,而且动作项目本身比我添加的要占用很多空间

这导致的另一个新问题是,点击溢出菜单附近的任何地方都会触发点击

编辑:

此解决方案的另一个问题是,在某些情况下,项目之间存在空格,例如,只有少数项目的情况下存在空格:


所以,简而言之,这个解决方案根本不起作用。

所以,如果我理解正确,您希望在工具栏中添加一些操作。这些操作应从左侧开始,并占用所有可用空间

您是否愿意将自定义视图(ImageView等)用于操作而不是MenuItem

将水平线性布局添加到工具栏。并为所有的孩子(动作)设置相等的权重


现在可以附加菜单以获得垂直3点动作。也可以在水平布局的末尾添加另一个固定宽度的ImageView

编辑:

我很快想出了一个解决办法。当然,您需要对代码进行一些改进。此解决方案使用自定义LinearLayout,它测量每个子级并决定是否需要溢出菜单。它将重新测量每个孩子,给所有孩子平等的空间

它使用PopupWindow来显示菜单,并使用简单的OnClickListener和回调来检查单击了哪个菜单项

FlexibleMenuContainer

public class FlexibleMenuContainer extends LinearLayout {

    private List<FlexibleMenu.MenuItem> items;

    private List<FlexibleMenu.MenuItem> drawableItems;
    private List<FlexibleMenu.MenuItem> overflowItems;

    private List<FlexibleMenu.MenuItem> overflowItemsTempContainer;

    private ImageView overflow;

    private int overflowViewSize;
    private boolean isOverflowing;

    public FlexibleMenuContainer(Context context) {
        this(context, null);
    }

    public FlexibleMenuContainer(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlexibleMenuContainer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        setOrientation(HORIZONTAL);
        items = new ArrayList<>();
        overflowItems = new ArrayList<>();
        drawableItems = new ArrayList<>();
        overflowItemsTempContainer = new ArrayList<>();

        overflowViewSize = getResources().getDimensionPixelOffset(R.dimen.menu_more_size);

        overflow = new ImageView(context);
        overflow.setImageResource(R.drawable.ic_more_vert_white_24dp);
        overflow.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                showOverflowMenu();
            }
        });
//      overflow.setVisibility(GONE);

        LinearLayout.LayoutParams params = new LayoutParams(overflowViewSize, overflowViewSize);
        params.gravity = Gravity.CENTER_VERTICAL;

        addView(overflow, params);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthRequired = 0;
        isOverflowing = false;
        overflowItems.clear();
        drawableItems.clear();

        if (items.size() == 0) {
            return;
        }

        int availableWidth = MeasureSpec.getSize(widthMeasureSpec) - overflowViewSize;

        for (int i=0; i<items.size(); i++) {
            View child = items.get(i).getView();
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            widthRequired += child.getMeasuredWidth();

            if (widthRequired > availableWidth) {
                isOverflowing = true;
                overflowItems.add(items.get(i));
            } else {
                drawableItems.add(items.get(i));
            }
        }

        int drawableWidth = MeasureSpec.getSize(widthMeasureSpec) - (isOverflowing ? overflowViewSize : 0);
        int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(drawableWidth/drawableItems.size(), MeasureSpec.EXACTLY);

        for (int i=0; i<drawableItems.size(); i++) {
            View child = drawableItems.get(i).getView();
            child.measure(childWidthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = 0;
        for (int i=0; i<drawableItems.size(); i++) {
            View child = drawableItems.get(i).getView();
            int height = Math.min(child.getMeasuredHeight(), b - t);
            int top = (b - t - height)/2;
            child.layout(left, top, left + child.getMeasuredWidth(), top + height);
            left += child.getMeasuredWidth();
        }

        if (isOverflowing) {
            overflow.layout(getMeasuredWidth() - overflowViewSize, t, getMeasuredWidth(), b);
        }

        // After opening the menu and dismissing it, the views are still laid out
        for (int i=0; i<overflowItems.size(); i++) {
            View child = overflowItems.get(i).getView();
            if (child.getParent() == this) {
                child.layout(0, 0, 0, 0);
            }
        }
    }

    public void addItem(FlexibleMenu.MenuItem item) {
        items.add(item);
        _addView(item.getView());
    }

    private void _addView(View view) {
        LinearLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.CENTER_VERTICAL;
        addView(view, getChildCount() - 1, params);
    }

    private void showOverflowMenu() {
        if (overflowItems.size() == 0) {
            return;
        }

        final ViewGroup contentView = prepareContentViewForPopup();
        final PopupWindow popup = new PopupWindow(contentView, 400, 300, true);
        popup.setOutsideTouchable(false);
        popup.setFocusable(true);
        popup.showAsDropDown(overflow);

        popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                contentView.removeAllViews();
                for (int i=0; i<overflowItemsTempContainer.size(); i++) {
                    View view = overflowItemsTempContainer.get(i).getView();
                    _addView(view);
                }

                overflowItemsTempContainer.clear();
            }
        });
    }

    private ViewGroup prepareContentViewForPopup() {
        overflowItemsTempContainer.clear();
        LinearLayout layout = new LinearLayout(getContext());
        layout.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
        layout.setOrientation(VERTICAL);
        for (int i=0; i<overflowItems.size(); i++) {
            overflowItemsTempContainer.add(overflowItems.get(i));
            View view = overflowItems.get(i).getView();
            removeView(view);
            layout.addView(view);
        }

        return layout;
    }

}
公共类FlexibleMenuContainer扩展了LinearLayout{
私人清单项目;
私人物品清单;
私有列表溢出项;
私有列表溢出项stempcontainer;
私有图像视图溢出;
私有int overflowViewSize;
私有布尔等溢出;
公共FlexibleMenuContainer(上下文){
这个(上下文,空);
}
公共FlexibleMenuContainer(上下文上下文,@Nullable AttributeSet attrs){
这(上下文,属性,0);
}
公共FlexibleMenuContainer(上下文上下文,@Nullable AttributeSet attrs,int-defStyleAttr){
super(上下文、attrs、defStyleAttr);
init(上下文,attrs);
}
私有void init(上下文上下文,@Nullable AttributeSet attrs){
设置方向(水平);
items=newarraylist();
overflowItems=新建ArrayList();
drawableItems=new ArrayList();
overflowItemsTempContainer=new ArrayList();
overflowViewSize=getResources().getDimensionPixelOffset(R.dimen.menu\u more\u size);
溢出=新图像视图(上下文);
溢出.setImageResource(R.drawable.ic\u more\u vert\u white\u 24dp);
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
showOverflowMenu();
}
});
//溢出。设置可见性(已消失);
LinearLayout.LayoutParams params=新的LayoutParams(overflowViewSize,overflowViewSize);
参数重力=重心垂直;
addView(溢出,参数);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
超级测量(宽度测量、高度测量);
int widthRequired=0;
等溢出=假;
overflowItems.clear();
drawableItems.clear();
如果(items.size()==0){
返回;
}
int availableWidth=MeasureSpec.getSize(widthmasurespec)-overflowViewSize;
for(int i=0;i可用宽度){
Isoverflow=真;
overflowItems.add(items.get(i));
}否则{
drawableItems.add(items.get(i));
}
}
int drawableWidth=MeasureSpec.getSize(widthMeasureSpec)-(IsOverflow?overflowViewSize:0);
int childwidthmasurespec=MeasureSpec.makeMeasureSpec(drawableWidth/drawableItems.size(),MeasureSpec.justly);

对于(int i=0;i,这里有一个解决方案,它将左对齐菜单项,同时将溢出菜单图标保持在右侧。此解决方案使用工具栏/操作栏的标准实现,但
public class FlexibleMenuContainer extends LinearLayout {

    private List<FlexibleMenu.MenuItem> items;

    private List<FlexibleMenu.MenuItem> drawableItems;
    private List<FlexibleMenu.MenuItem> overflowItems;

    private List<FlexibleMenu.MenuItem> overflowItemsTempContainer;

    private ImageView overflow;

    private int overflowViewSize;
    private boolean isOverflowing;

    public FlexibleMenuContainer(Context context) {
        this(context, null);
    }

    public FlexibleMenuContainer(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlexibleMenuContainer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        setOrientation(HORIZONTAL);
        items = new ArrayList<>();
        overflowItems = new ArrayList<>();
        drawableItems = new ArrayList<>();
        overflowItemsTempContainer = new ArrayList<>();

        overflowViewSize = getResources().getDimensionPixelOffset(R.dimen.menu_more_size);

        overflow = new ImageView(context);
        overflow.setImageResource(R.drawable.ic_more_vert_white_24dp);
        overflow.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                showOverflowMenu();
            }
        });
//      overflow.setVisibility(GONE);

        LinearLayout.LayoutParams params = new LayoutParams(overflowViewSize, overflowViewSize);
        params.gravity = Gravity.CENTER_VERTICAL;

        addView(overflow, params);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthRequired = 0;
        isOverflowing = false;
        overflowItems.clear();
        drawableItems.clear();

        if (items.size() == 0) {
            return;
        }

        int availableWidth = MeasureSpec.getSize(widthMeasureSpec) - overflowViewSize;

        for (int i=0; i<items.size(); i++) {
            View child = items.get(i).getView();
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            widthRequired += child.getMeasuredWidth();

            if (widthRequired > availableWidth) {
                isOverflowing = true;
                overflowItems.add(items.get(i));
            } else {
                drawableItems.add(items.get(i));
            }
        }

        int drawableWidth = MeasureSpec.getSize(widthMeasureSpec) - (isOverflowing ? overflowViewSize : 0);
        int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(drawableWidth/drawableItems.size(), MeasureSpec.EXACTLY);

        for (int i=0; i<drawableItems.size(); i++) {
            View child = drawableItems.get(i).getView();
            child.measure(childWidthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = 0;
        for (int i=0; i<drawableItems.size(); i++) {
            View child = drawableItems.get(i).getView();
            int height = Math.min(child.getMeasuredHeight(), b - t);
            int top = (b - t - height)/2;
            child.layout(left, top, left + child.getMeasuredWidth(), top + height);
            left += child.getMeasuredWidth();
        }

        if (isOverflowing) {
            overflow.layout(getMeasuredWidth() - overflowViewSize, t, getMeasuredWidth(), b);
        }

        // After opening the menu and dismissing it, the views are still laid out
        for (int i=0; i<overflowItems.size(); i++) {
            View child = overflowItems.get(i).getView();
            if (child.getParent() == this) {
                child.layout(0, 0, 0, 0);
            }
        }
    }

    public void addItem(FlexibleMenu.MenuItem item) {
        items.add(item);
        _addView(item.getView());
    }

    private void _addView(View view) {
        LinearLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.CENTER_VERTICAL;
        addView(view, getChildCount() - 1, params);
    }

    private void showOverflowMenu() {
        if (overflowItems.size() == 0) {
            return;
        }

        final ViewGroup contentView = prepareContentViewForPopup();
        final PopupWindow popup = new PopupWindow(contentView, 400, 300, true);
        popup.setOutsideTouchable(false);
        popup.setFocusable(true);
        popup.showAsDropDown(overflow);

        popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                contentView.removeAllViews();
                for (int i=0; i<overflowItemsTempContainer.size(); i++) {
                    View view = overflowItemsTempContainer.get(i).getView();
                    _addView(view);
                }

                overflowItemsTempContainer.clear();
            }
        });
    }

    private ViewGroup prepareContentViewForPopup() {
        overflowItemsTempContainer.clear();
        LinearLayout layout = new LinearLayout(getContext());
        layout.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
        layout.setOrientation(VERTICAL);
        for (int i=0; i<overflowItems.size(); i++) {
            overflowItemsTempContainer.add(overflowItems.get(i));
            View view = overflowItems.get(i).getView();
            removeView(view);
            layout.addView(view);
        }

        return layout;
    }

}
public class FlexibleMenu {

    private final List<MenuItem> items;
    private final MenuCallback callback;

    public FlexibleMenu(List<MenuItem> items, MenuCallback callback) {
        this.items = items;
        this.callback = callback;
    }

    public void inflate(FlexibleMenuContainer container) {
        for (int i=0; i<items.size(); i++) {
            final MenuItem item = items.get(i);
            container.addItem(item);
            item.getView().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callback.onItemClicked(item);
                }
            });
        }
    }

    public interface MenuCallback {
        void onItemClicked(MenuItem item);
    }

    public static class MenuItem {

        private final int id;
        private final View view;

        public MenuItem(int id, View view) {
            this.id = id;
            this.view = view;
        }

        public View getView() {
            return view;
        }

        public int getId() {
            return id;
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:orientation="vertical"
    tools:context="com.fenchtose.flexiblemenu.MainActivity">

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:paddingStart="0dp"
        android:background="@color/colorPrimary">

        <com.fenchtose.flexiblemenu.FlexibleMenuContainer
            android:id="@+id/menu_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </android.support.v7.widget.Toolbar>

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:paddingStart="0dp"
        android:background="@color/colorPrimary">

        <com.fenchtose.flexiblemenu.FlexibleMenuContainer
            android:id="@+id/menu_container1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </android.support.v7.widget.Toolbar>

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:paddingStart="0dp"
        android:background="@color/colorPrimary">

        <com.fenchtose.flexiblemenu.FlexibleMenuContainer
            android:id="@+id/menu_container2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </android.support.v7.widget.Toolbar>

</LinearLayout>
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupMenu(R.id.menu_container, 6);
        setupMenu(R.id.menu_container1, 2);
        setupMenu(R.id.menu_container2, 4);
    }

    private void setupMenu(int id, int size) {
        FlexibleMenuContainer container = (FlexibleMenuContainer) findViewById(id);
        FlexibleMenu menu = new FlexibleMenu(populate(size), new FlexibleMenu.MenuCallback() {
            @Override
            public void onItemClicked(FlexibleMenu.MenuItem item) {
                Toast.makeText(MainActivity.this, "menu selected: " + item.getId(), Toast.LENGTH_SHORT).show();
            }
        });
        menu.inflate(container);
    }

    private List<FlexibleMenu.MenuItem> populate(int size) {
        List<FlexibleMenu.MenuItem> items = new ArrayList<>();
        for (int i=0; i<size; i++) {
            View view = createView("Menu Item " + (i + 1));
            items.add(new FlexibleMenu.MenuItem(i, view));
        }

        return items;
    }

    private TextView createView(String text) {
        TextView view = new TextView(this);
        view.setText(text);
        view.setGravity(Gravity.CENTER);
        view.setTextColor(0xffffffff);
        return view;
    }
}
public class MainActivity extends AppCompatActivity {
    private Toolbar mToolbar;

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

        mToolbar = findViewById(R.id.toolbar);
        mToolbar.setTitle("");
        setSupportActionBar(mToolbar); // Ensures that onCreateOptionsMenu is called
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        final float density = getResources().getDisplayMetrics().density;
        final int overflowCellSize = (int) (OVERFLOW_CELL_WIDTH * density);
        // Other than the overflow icon, this is how much real estate we have to fill.
        int widthLeftToFill = mToolbar.getWidth() - overflowCellSize;
        // slackWidth is what is left over after we are done adding our action views.
        int slackWidth = -1;

        for (int i = 0; i < 10; ++i) {
            final View menuItemView =
                    LayoutInflater.from(this).inflate(R.layout.action_item, mToolbar, false);
            ImageView imageView = menuItemView.findViewById(android.R.id.icon);
            final int itemIconResId = R.drawable.ic_launcher_background;
            imageView.setImageResource(itemIconResId);
            final String text = "item" + i;
            ((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
            final View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(final View view) {
                    Toast.makeText(MainActivity.this, text,
                            Toast.LENGTH_SHORT).show();
                }
            };
            menuItemView.setOnClickListener(onClickListener);
            final MenuItem menuItem = menu
                    .add(text).setActionView(menuItemView).setIcon(itemIconResId)
                    .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                        @SuppressLint("MissingPermission")
                        @Override
                        public boolean onMenuItemClick(final MenuItem menuItem) {
                            onClickListener.onClick(menuItemView);
                            return true;
                        }
                    });
            // How wide is this ActionView?
            menuItemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            widthLeftToFill -= menuItemView.getMeasuredWidth();
            if (widthLeftToFill >= 0) {
                // The item will fit on the screen.
                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
            } else {
                // The item will not fit. Force it to overflow.
                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
                if (slackWidth < 0) {
                    // Just crossed over the limit of space to fill - capture the slack space.
                    slackWidth = widthLeftToFill + menuItemView.getMeasuredWidth();
                }
            }
        }
        if (slackWidth < 0) {
            // Didn't have enough action views to fill the width.
            slackWidth = widthLeftToFill + overflowCellSize;
        }
        if (slackWidth > 0) {
            // Create a space widget to consume the slack. This slack space widget makes sure
            // that the action views are left-justified with the overflow on the right.
            // As an alternative, this space could also be distributed among the action views.
            Space space = new Space(this);
            space.setMinimumWidth(slackWidth);
            final MenuItem menuItem = menu.add("").setActionView(space);
            menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }
        return true;
    }

    private static final int OVERFLOW_CELL_WIDTH = 40; // dips
}
<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=".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">
    </android.support.v7.widget.Toolbar>
</FrameLayout>
<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"
    android:paddingLeft="8dp">
    <ImageView
        android:id="@android:id/icon"
        android:layout_width="wrap_content"
        android:layout_height="?attr/actionBarSize"
        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="?attr/actionBarSize"
        android:layout_marginLeft="6dp"
        android:layout_marginStart="6dp"
        android:gravity="center"
        android:textColor="#c2555555"
        android:textSize="15sp"
        tools:text="text" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
    private Toolbar mToolbar;

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

        mToolbar = findViewById(R.id.toolbar);
        mToolbar.setTitle("");
//        setSupportActionBar(mToolbar); // Ensures that onCreateOptionsMenu is called
        mToolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mToolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                setupMenu(mToolbar.getMenu());
            }
        });
    }

    public boolean setupMenu(Menu menu) {
        final float density = getResources().getDisplayMetrics().density;
        int mOverflowCellSize = (int) (OVERFLOW_CELL_WIDTH * density);
        // Other than the overflow icon, this is how much real estate we have to fill.
        int widthLeftToFill = mToolbar.getWidth() - mOverflowCellSize;
        // slackWidth is what is left over after we are done adding our action views.
        int slackWidth = -1;

        for (int i = 0; i < 10; ++i) {
            final View menuItemView =
                    LayoutInflater.from(this).inflate(R.layout.action_item, mToolbar, false);
            ImageView imageView = menuItemView.findViewById(android.R.id.icon);
            final int itemIconResId = R.drawable.ic_launcher_background;
            imageView.setImageResource(itemIconResId);
            String text = "item" + i;
            ((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
            final View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(final View view) {
                    Toast.makeText(MainActivity.this, text ,
                            Toast.LENGTH_SHORT).show();
                }
            };
            menuItemView.setOnClickListener(onClickListener);
            final MenuItem menuItem = menu
                    .add(text).setActionView(menuItemView).setIcon(itemIconResId)
                    .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                        @SuppressLint("MissingPermission")
                        @Override
                        public boolean onMenuItemClick(final MenuItem menuItem) {
                            onClickListener.onClick(menuItemView);
                            return true;
                        }
                    });
            // How wide is this ActionView?
            menuItemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            widthLeftToFill -= menuItemView.getMeasuredWidth();
            if (widthLeftToFill >= 0) {
                // The item will fit on the screen.
                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
            } else {
                // The item will not fit. Force it to overflow.
                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
                if (slackWidth < 0) {
                    // Just crossed over the limit of space to fill - capture the slack space.
                    slackWidth = widthLeftToFill + menuItemView.getMeasuredWidth();
                }
            }
        }
        if (slackWidth < 0) {
            // Didn't have enough action views to fill the width.
            slackWidth = widthLeftToFill + mOverflowCellSize;
        }
        if (slackWidth > 0) {
            // Create a space widget to consume the slack. This slack space widget makes sure
            // that the action views are left-justified with the overflow on the right.
            // As an alternative, this space could also be distributed among the action views.
            Space space = new Space(this);
            space.setMinimumWidth(slackWidth);
            final MenuItem menuItem = menu.add("").setActionView(space);
            menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }
        return true;
    }

    private static final int OVERFLOW_CELL_WIDTH = 40; // dips
}
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle("");
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Menu menu = toolbar.getMenu();
                // Remove item at position 1 on click of button.
                if (menu.size() > 1) {
                    menu.removeItem(menu.getItem(1).getItemId());
                    notifyMenuItemsChanged(toolbar);
                }
            }
        });
        toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                setupMenu(toolbar);
            }
        });
    }

    private void setupMenu(Toolbar toolbar) {
        Menu menu = toolbar.getMenu();

        // Since we are resetting the menu, get rid of what may have been placed there before.
        menu.clear();
        for (int i = 0; i < 10; ++i) {
            final View menuItemView =
                    LayoutInflater.from(this).inflate(R.layout.action_item, toolbar, false);
            ImageView imageView = menuItemView.findViewById(android.R.id.icon);
            final int itemIconResId = R.drawable.ic_launcher_background;
            imageView.setImageResource(itemIconResId);
            String text = "item" + i;
            ((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
            final View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(final View view) {
                    Toast.makeText(MainActivity.this, text ,
                            Toast.LENGTH_SHORT).show();
                }
            };
            menuItemView.setOnClickListener(onClickListener);
            menu.add(Menu.NONE, View.generateViewId(), Menu.NONE, text)
                    .setActionView(menuItemView)
                    .setIcon(itemIconResId)
                    .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                        @SuppressLint("MissingPermission")
                        @Override
                        public boolean onMenuItemClick(final MenuItem menuItem) {
                            onClickListener.onClick(menuItemView);
                            return true;
                        }
                    });
        }
        // Now take the menu and left-justify it.
        notifyMenuItemsChanged(toolbar);
    }

    /**
     * Call this routine whenever the Toolbar menu changes. Take all action views and
     * left-justify those that fit on the screen. Force to overflow those that don't.
     *
     * @param toolbar The Toolbar that holds the menu.
     */
    private void notifyMenuItemsChanged(Toolbar toolbar) {
        final int OVERFLOW_CELL_WIDTH = 40; // dips
        final Menu menu = toolbar.getMenu();
        final float density = getResources().getDisplayMetrics().density;
        final int mOverflowCellSize = (int) (OVERFLOW_CELL_WIDTH * density);
        // Other than the overflow icon, this is how much real estate we have to fill.
        int widthLeftToFill = toolbar.getWidth() - mOverflowCellSize;
        // slackWidth is what is left over after we are done adding our action views.
        int slackWidth = -1;
        MenuItem menuItem;
        // Index of the spacer that will be removed/replaced.
        int spaceIndex = View.NO_ID;

        if (menu.size() == 0) {
            return;
        }

        // Examine each MenuItemView to determine if it will fit on the screen. If it can,
        // set its MenuItem to always show; otherwise, set the MenuItem to never show.
        for (int i = 0; i < menu.size(); i++) {
            menuItem = menu.getItem(i);
            View menuItemView = menuItem.getActionView();
            if (menuItemView instanceof Space) {
                spaceIndex = menuItem.getItemId();
                continue;
            }
            if (!menuItem.isVisible()) {
                continue;
            }
            // How wide is this ActionView?
            menuItemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            widthLeftToFill -= menuItemView.getMeasuredWidth();
            if (widthLeftToFill >= 0) {
                // The item will fit on the screen.
                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
            } else {
                // The item will not fit. Force it to overflow.
                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
                if (slackWidth < 0) {
                    // Just crossed over the limit of space to fill - capture the slack space.
                    slackWidth = widthLeftToFill + menuItemView.getMeasuredWidth();
                }
            }
        }
        if (spaceIndex != View.NO_ID) {
            // Assume that this is our spacer. It may need to change size, so eliminate it for now.
            menu.removeItem(spaceIndex);
        }
        if (slackWidth < 0) {
            // Didn't have enough action views to fill the width, so there is no overflow.
            slackWidth = widthLeftToFill + mOverflowCellSize;
        }
        if (slackWidth > 0) {
            // Create a space widget to consume the slack. This slack space widget makes sure
            // that the action views are left-justified with the overflow on the right.
            // As an alternative, this space could also be distributed among the action views.
            Space space = new Space(this);
            space.setMinimumWidth(slackWidth);
            // Need an if for the spacer so it can be deleted later if the menu is modified.
            // Need API 17+ for generateViewId().
            menuItem = menu.add(Menu.NONE, View.generateViewId(), Menu.NONE, "")
                    .setActionView(space);
            menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }
    }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Click the button to add/remove item #1 from the menu."/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Click to modify menu" />

</LinearLayout>