如何将所有操作项放在左侧,占用尽可能多的空间,而右侧又溢出呢? [英] How to put all action items on the left, taking as much space as possible, and yet have overflow on the right?

查看:91
本文介绍了如何将所有操作项放在左侧,占用尽可能多的空间,而右侧又溢出呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个工具栏和多个操作项.有些可能是自定义的(例如:带图像的TextView).

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.

我发现的任何方法都不起作用

None of what I've found works

1.为了对齐,我在StackOverflow上找到了一些解决方案,可以在工具栏内添加视图,但是由于某些原因,这种方法不能很好地工作,因为按一个项目并不能显示对整个项目的影响(好像高度较小).

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"-对操作项没有任何作用
  • android:gravity="left|start"-相同
  • android:layoutDirection="ltr" - doesn't do anything to the action items
  • android:gravity="left|start" - same

2.对于空间问题,我尝试的所有方法均无效.我试图删除所有可能增加边距或填充的内容.

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>

这就是我得到的:

我如何支持工具栏的最大空间使用,并使操作项向左对齐?

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

经过一些工作,我得到了部分解决方案的对齐解决方案:

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>

在代码中,唯一的区别是我使用ActionMenuView的菜单而不是工具栏:

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:

为了解决紧迫效果的问题,我要做的就是将android:minHeight =?attr/actionBarSize"添加到循环中被夸大的项目中.

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.

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

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:

因此,简而言之,此解决方案根本无法正常工作.

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

推荐答案

此处是一种解决方案,它将使菜单项左对齐,同时将溢出菜单图标保持在右侧.此解决方案使用工具栏/操作栏的标准实现,但可以预期如何布置操作视图,以便将它们放置在我们希望的工具栏中.

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.

下面的大多数代码都是您所提供的.我已经将创建菜单项的for循环移到了onCreateOptionsMenu()中,因此我可以使用已经属于工具栏菜单结构一部分的ActionMenuView,而不必添加其他菜单项.

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.

onCreateOptionsMenu()中,当菜单项放置在菜单中时,菜单项所消耗的空间会保持连续运行.只要有空间,菜单项就会被标记为已显示"(MenuItem.SHOW_AS_ACTION_ALWAYS).如果该项目会侵占为溢出菜单图标保留的区域,则该项目已放置,但以溢出菜单(MenuItem.SHOW_AS_ACTION_NEVER)为目标.

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

一旦计算出松弛空间,就会创建一个Space小部件并将其放置在菜单中.此小部件会强制所有其他项目左对齐.

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.

MainActivity.java进行了大多数更改,但是我可能已经更改了XML文件中的一两个内容.为了完整起见,我将它们包括在这里.

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

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
}

activity_main.xml

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

action_item.xml

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


更新:要在不将其设置为操作栏的情况下使用工具栏,请添加全局布局侦听器,直到设置工具栏.


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 -使用全局布局侦听器而不是操作栏

MainActivity.java - using a global layout listener instead of an action bar

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
}


以下示例应用程序通过引入方法notifyMenuItemsChanged将菜单创建与菜单的左对齐分开.在应用程序中,单击按钮以删除位置1处的菜单项.


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.

此代码与上面的代码基本相同,但是Space小部件需要一个ID,以便可以在菜单更改时将其删除并重新添加.

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 :示例应用

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

activity_main.xml:示例应用

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

这篇关于如何将所有操作项放在左侧,占用尽可能多的空间,而右侧又溢出呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆