How To Put All Action Items On The Left, Taking As Much Space As Possible, And Yet Have Overflow On The Right?
Solution 1:
So if I understand this correctly, you want to add some actions in Toolbar. These actions should start from left and take all the space that is available.
Are you open to using custom views (ImageView, etc) for actions instead of MenuItem?
Add a horizontal LinearLayout to your Toolbar. And set equal weight to all the children (actions).
<Toolbar><LinearLayouthorizontal><ImageViewlayout_width="0dp"layout_weight="1" /><ImageViewlayout_width="0dp"layout_weight="1" /><ImageViewlayout_width="0dp"layout_weight="1" /></LinearLayout></Toolbar>
You can now attach menu to get vertical 3 dots action. Or you can add another ImageView at the end of the horizontal layout with fixed width.
EDIT:
Here's a solution that I quickly came up with. You will of course need to refine the code a bit. This solution uses a custom LinearLayout which measures each child and decides if overflow menu will be required or not. It will remeasure each child again to give equal space to all.
It uses PopupWindow to show menu and simple OnClickListener and callback to check which menu item was clicked.
FlexibleMenuContainer
publicclassFlexibleMenuContainerextendsLinearLayout {
private List<FlexibleMenu.MenuItem> items;
private List<FlexibleMenu.MenuItem> drawableItems;
private List<FlexibleMenu.MenuItem> overflowItems;
private List<FlexibleMenu.MenuItem> overflowItemsTempContainer;
private ImageView overflow;
privateint overflowViewSize;
privateboolean isOverflowing;
publicFlexibleMenuContainer(Context context) {
this(context, null);
}
publicFlexibleMenuContainer(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
publicFlexibleMenuContainer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
privatevoidinit(Context context, @Nullable AttributeSet attrs) {
setOrientation(HORIZONTAL);
items = newArrayList<>();
overflowItems = newArrayList<>();
drawableItems = newArrayList<>();
overflowItemsTempContainer = newArrayList<>();
overflowViewSize = getResources().getDimensionPixelOffset(R.dimen.menu_more_size);
overflow = newImageView(context);
overflow.setImageResource(R.drawable.ic_more_vert_white_24dp);
overflow.setOnClickListener(newOnClickListener() {
@OverridepublicvoidonClick(View v) {
showOverflowMenu();
}
});
// overflow.setVisibility(GONE);
LinearLayout.LayoutParamsparams=newLayoutParams(overflowViewSize, overflowViewSize);
params.gravity = Gravity.CENTER_VERTICAL;
addView(overflow, params);
}
@OverrideprotectedvoidonMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
intwidthRequired=0;
isOverflowing = false;
overflowItems.clear();
drawableItems.clear();
if (items.size() == 0) {
return;
}
intavailableWidth= MeasureSpec.getSize(widthMeasureSpec) - overflowViewSize;
for (int i=0; i<items.size(); i++) {
Viewchild= 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));
}
}
intdrawableWidth= MeasureSpec.getSize(widthMeasureSpec) - (isOverflowing ? overflowViewSize : 0);
intchildWidthMeasureSpec= MeasureSpec.makeMeasureSpec(drawableWidth/drawableItems.size(), MeasureSpec.EXACTLY);
for (int i=0; i<drawableItems.size(); i++) {
Viewchild= drawableItems.get(i).getView();
child.measure(childWidthMeasureSpec, heightMeasureSpec);
}
}
@OverrideprotectedvoidonLayout(boolean changed, int l, int t, int r, int b) {
intleft=0;
for (int i=0; i<drawableItems.size(); i++) {
Viewchild= drawableItems.get(i).getView();
intheight= Math.min(child.getMeasuredHeight(), b - t);
inttop= (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 outfor (int i=0; i<overflowItems.size(); i++) {
Viewchild= overflowItems.get(i).getView();
if (child.getParent() == this) {
child.layout(0, 0, 0, 0);
}
}
}
publicvoidaddItem(FlexibleMenu.MenuItem item) {
items.add(item);
_addView(item.getView());
}
privatevoid_addView(View view) {
LinearLayout.LayoutParamsparams=newLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_VERTICAL;
addView(view, getChildCount() - 1, params);
}
privatevoidshowOverflowMenu() {
if (overflowItems.size() == 0) {
return;
}
finalViewGroupcontentView= prepareContentViewForPopup();
finalPopupWindowpopup=newPopupWindow(contentView, 400, 300, true);
popup.setOutsideTouchable(false);
popup.setFocusable(true);
popup.showAsDropDown(overflow);
popup.setOnDismissListener(newPopupWindow.OnDismissListener() {
@OverridepublicvoidonDismiss() {
contentView.removeAllViews();
for (int i=0; i<overflowItemsTempContainer.size(); i++) {
Viewview= overflowItemsTempContainer.get(i).getView();
_addView(view);
}
overflowItemsTempContainer.clear();
}
});
}
private ViewGroup prepareContentViewForPopup() {
overflowItemsTempContainer.clear();
LinearLayoutlayout=newLinearLayout(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));
Viewview= overflowItems.get(i).getView();
removeView(view);
layout.addView(view);
}
return layout;
}
}
FlexibleMenu
publicclassFlexibleMenu {
privatefinal List<MenuItem> items;
privatefinal MenuCallback callback;
publicFlexibleMenu(List<MenuItem> items, MenuCallback callback) {
this.items = items;
this.callback = callback;
}
publicvoidinflate(FlexibleMenuContainer container) {
for (int i=0; i<items.size(); i++) {
finalMenuItemitem= items.get(i);
container.addItem(item);
item.getView().setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View v) {
callback.onItemClicked(item);
}
});
}
}
publicinterfaceMenuCallback {
voidonItemClicked(MenuItem item);
}
publicstaticclassMenuItem {
privatefinalint id;
privatefinal View view;
publicMenuItem(int id, View view) {
this.id = id;
this.view = view;
}
public View getView() {
return view;
}
publicintgetId() {
return id;
}
}
}
layout
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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.Toolbarandroid:layout_width="match_parent"android:layout_height="56dp"android:paddingStart="0dp"android:background="@color/colorPrimary"><com.fenchtose.flexiblemenu.FlexibleMenuContainerandroid:id="@+id/menu_container"android:layout_width="match_parent"android:layout_height="match_parent"/></android.support.v7.widget.Toolbar><android.support.v7.widget.Toolbarandroid:layout_width="match_parent"android:layout_height="56dp"android:paddingStart="0dp"android:background="@color/colorPrimary"><com.fenchtose.flexiblemenu.FlexibleMenuContainerandroid:id="@+id/menu_container1"android:layout_width="match_parent"android:layout_height="match_parent"/></android.support.v7.widget.Toolbar><android.support.v7.widget.Toolbarandroid:layout_width="match_parent"android:layout_height="56dp"android:paddingStart="0dp"android:background="@color/colorPrimary"><com.fenchtose.flexiblemenu.FlexibleMenuContainerandroid:id="@+id/menu_container2"android:layout_width="match_parent"android:layout_height="match_parent"/></android.support.v7.widget.Toolbar></LinearLayout>
MainActivity
publicclassMainActivityextendsAppCompatActivity {
@OverrideprotectedvoidonCreate(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);
}
privatevoidsetupMenu(int id, int size) {
FlexibleMenuContainercontainer= (FlexibleMenuContainer) findViewById(id);
FlexibleMenumenu=newFlexibleMenu(populate(size), newFlexibleMenu.MenuCallback() {
@OverridepublicvoidonItemClicked(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 = newArrayList<>();
for (int i=0; i<size; i++) {
Viewview= createView("Menu Item " + (i + 1));
items.add(newFlexibleMenu.MenuItem(i, view));
}
return items;
}
private TextView createView(String text) {
TextViewview=newTextView(this);
view.setText(text);
view.setGravity(Gravity.CENTER);
view.setTextColor(0xffffffff);
return view;
}
}
Solution 2:
Here is a solution that will left-justify the menu items while keeping the overflow menu icon to the right. This solution uses the standard implementation of the toolbar/action bar but anticipates how action views will be laid out so they will be positioned as we wish in the toolbar.
Most of the code below is what you have presented. I have moved the for
loop that creates the menu items into onCreateOptionsMenu()
so I could make use of the ActionMenuView
that is already part of the toolbar's menu structure instead of adding another one.
In onCreateOptionsMenu()
a running tally of space consumed by menu items is maintained as menu items are laid into the menu. As long as there is space, menu items will be flagged as "shown" (MenuItem.SHOW_AS_ACTION_ALWAYS). If the item will encroach on the area reserved for the overflow menu icon, the item is laid in but is targeted for the overflow menu (MenuItem.SHOW_AS_ACTION_NEVER).
After all views are laid into the menu, the slack space is computed. This is the area on the screen between the last visible menu item and the overflow icon (if overflow is in used) or between the last visible item and the end of the tool bar (if overflow is not in use.)
Once the slack space is computed, a Space
widget is created and laid into the menu. This widget forces all other items to be left-justified.
Most of the changes have been made to MainActivity.java
, but I may have changed a thing or two in the XML files. I include them here for completeness.
Here are some screen captures of the results.
MainActivity.java
publicclassMainActivityextendsAppCompatActivity {
private Toolbar mToolbar;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = findViewById(R.id.toolbar);
mToolbar.setTitle("");
setSupportActionBar(mToolbar); // Ensures that onCreateOptionsMenu is called
}
@OverridepublicbooleanonCreateOptionsMenu(Menu menu) {
finalfloatdensity= getResources().getDisplayMetrics().density;
finalintoverflowCellSize= (int) (OVERFLOW_CELL_WIDTH * density);
// Other than the overflow icon, this is how much real estate we have to fill.intwidthLeftToFill= mToolbar.getWidth() - overflowCellSize;
// slackWidth is what is left over after we are done adding our action views.intslackWidth= -1;
for (inti=0; i < 10; ++i) {
finalViewmenuItemView=
LayoutInflater.from(this).inflate(R.layout.action_item, mToolbar, false);
ImageViewimageView= menuItemView.findViewById(android.R.id.icon);
finalintitemIconResId= R.drawable.ic_launcher_background;
imageView.setImageResource(itemIconResId);
finalStringtext="item" + i;
((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
final View.OnClickListeneronClickListener=newView.OnClickListener() {
@OverridepublicvoidonClick(final View view) {
Toast.makeText(MainActivity.this, text,
Toast.LENGTH_SHORT).show();
}
};
menuItemView.setOnClickListener(onClickListener);
finalMenuItemmenuItem= menu
.add(text).setActionView(menuItemView).setIcon(itemIconResId)
.setOnMenuItemClickListener(newMenuItem.OnMenuItemClickListener() {
@SuppressLint("MissingPermission")@OverridepublicbooleanonMenuItemClick(final MenuItem menuItem) {
onClickListener.onClick(menuItemView);
returntrue;
}
});
// 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.Spacespace=newSpace(this);
space.setMinimumWidth(slackWidth);
finalMenuItemmenuItem= menu.add("").setActionView(space);
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
returntrue;
}
privatestaticfinalintOVERFLOW_CELL_WIDTH=40; // dips
}
activity_main.xml
<FrameLayoutxmlns: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.Toolbarandroid: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>
action_item.xml
<LinearLayoutxmlns: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"><ImageViewandroid: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" /><TextViewandroid: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>
Update: To use the tool bar without setting it up as an action bar, add a global layout listener to wait until the tool bar is setup.
MainActivity.java - using a global layout listener instead of an action bar
publicclassMainActivityextendsAppCompatActivity {
private Toolbar mToolbar;
@OverrideprotectedvoidonCreate(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(newViewTreeObserver.OnGlobalLayoutListener() {
@OverridepublicvoidonGlobalLayout() {
mToolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
setupMenu(mToolbar.getMenu());
}
});
}
publicbooleansetupMenu(Menu menu) {
finalfloatdensity= getResources().getDisplayMetrics().density;
intmOverflowCellSize= (int) (OVERFLOW_CELL_WIDTH * density);
// Other than the overflow icon, this is how much real estate we have to fill.intwidthLeftToFill= mToolbar.getWidth() - mOverflowCellSize;
// slackWidth is what is left over after we are done adding our action views.intslackWidth= -1;
for (inti=0; i < 10; ++i) {
finalViewmenuItemView=
LayoutInflater.from(this).inflate(R.layout.action_item, mToolbar, false);
ImageViewimageView= menuItemView.findViewById(android.R.id.icon);
finalintitemIconResId= R.drawable.ic_launcher_background;
imageView.setImageResource(itemIconResId);
Stringtext="item" + i;
((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
final View.OnClickListeneronClickListener=newView.OnClickListener() {
@OverridepublicvoidonClick(final View view) {
Toast.makeText(MainActivity.this, text ,
Toast.LENGTH_SHORT).show();
}
};
menuItemView.setOnClickListener(onClickListener);
finalMenuItemmenuItem= menu
.add(text).setActionView(menuItemView).setIcon(itemIconResId)
.setOnMenuItemClickListener(newMenuItem.OnMenuItemClickListener() {
@SuppressLint("MissingPermission")@OverridepublicbooleanonMenuItemClick(final MenuItem menuItem) {
onClickListener.onClick(menuItemView);
returntrue;
}
});
// 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.Spacespace=newSpace(this);
space.setMinimumWidth(slackWidth);
finalMenuItemmenuItem= menu.add("").setActionView(space);
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
returntrue;
}
privatestaticfinalintOVERFLOW_CELL_WIDTH=40; // dips
}
The following sample app separates out menu creation from the left justification of the menu by introducing the method notifyMenuItemsChanged
. In the app, click on the button to remove the menu item at position 1.
This code is basically the same as above, but the Space
widget needs an id so it can be removed to be re-added when the menu changes.
MainActivity.Java: Sample app
publicclassMainActivityextendsAppCompatActivity {
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
finalToolbartoolbar= findViewById(R.id.toolbar);
toolbar.setTitle("");
findViewById(R.id.button).setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View view) {
Menumenu= 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(newViewTreeObserver.OnGlobalLayoutListener() {
@OverridepublicvoidonGlobalLayout() {
toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
setupMenu(toolbar);
}
});
}
privatevoidsetupMenu(Toolbar toolbar) {
Menumenu= toolbar.getMenu();
// Since we are resetting the menu, get rid of what may have been placed there before.
menu.clear();
for (inti=0; i < 10; ++i) {
finalViewmenuItemView=
LayoutInflater.from(this).inflate(R.layout.action_item, toolbar, false);
ImageViewimageView= menuItemView.findViewById(android.R.id.icon);
finalintitemIconResId= R.drawable.ic_launcher_background;
imageView.setImageResource(itemIconResId);
Stringtext="item" + i;
((TextView) menuItemView.findViewById(android.R.id.text1)).setText(text);
final View.OnClickListeneronClickListener=newView.OnClickListener() {
@OverridepublicvoidonClick(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(newMenuItem.OnMenuItemClickListener() {
@SuppressLint("MissingPermission")@OverridepublicbooleanonMenuItemClick(final MenuItem menuItem) {
onClickListener.onClick(menuItemView);
returntrue;
}
});
}
// 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.
*/privatevoidnotifyMenuItemsChanged(Toolbar toolbar) {
finalintOVERFLOW_CELL_WIDTH=40; // dipsfinalMenumenu= toolbar.getMenu();
finalfloatdensity= getResources().getDisplayMetrics().density;
finalintmOverflowCellSize= (int) (OVERFLOW_CELL_WIDTH * density);
// Other than the overflow icon, this is how much real estate we have to fill.intwidthLeftToFill= toolbar.getWidth() - mOverflowCellSize;
// slackWidth is what is left over after we are done adding our action views.intslackWidth= -1;
MenuItem menuItem;
// Index of the spacer that will be removed/replaced.intspaceIndex= 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 (inti=0; i < menu.size(); i++) {
menuItem = menu.getItem(i);
ViewmenuItemView= 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.Spacespace=newSpace(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);
}
}
}
activity_main.xml: Sample app
<LinearLayoutxmlns: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.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize" /><TextViewandroid: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."/><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Click to modify menu" /></LinearLayout>
Post a Comment for "How To Put All Action Items On The Left, Taking As Much Space As Possible, And Yet Have Overflow On The Right?"