如何在ActionBar上更改菜单项的位置

15

我正在开发一个应用程序,需要在操作栏上添加自定义布局。已经完成了添加自定义布局的过程,但是当我在操作栏上添加菜单项时,我的自定义布局从操作栏右侧移动到了操作栏中央。下面是我目前的实现情况:

Done till here

我想要的效果是这样的:

Like this

自定义布局(黄色按钮)位于操作栏的最右侧,而菜单项则在中间。

以下是我使用本机Android操作栏实现此自定义布局的代码:

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

    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    actionBar = getActionBar();
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayUseLogoEnabled(false);
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setDisplayShowCustomEnabled(true);
    cView = getLayoutInflater().inflate(R.layout.header, null);
    actionBar.setCustomView(cView);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.websearch_menu, menu);
    return true;

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {

    case android.R.id.home:
        finish();

    default:
        return super.onOptionsItemSelected(item);
    }
}

如何实现这个目标?

任何形式的帮助都将不胜感激。

4个回答

18

只需在您的xml文件中使用orderInCategory,它将按从小到大的顺序进行排序(从操作栏左侧开始)。例如:

只需要在您的xml文件中使用orderInCategory属性,它会使得菜单项按照从小到大(从操作栏左侧开始)的顺序排序。例如:

<item
    android:id="@+id/Refresh"
    android:icon="@drawable/ic_action_refresh"
    android:showAsAction="ifRoom"
    android:title="@string/refresh"
    android:orderInCategory="2"/>
<item
    android:id="@+id/Search"
    android:icon="@drawable/ic_action_action_search"
    android:showAsAction="ifRoom|collapseActionView"
    android:title="@string/search"
    android:orderInCategory="1"/>

尽管在 xml 文件中,Refresh 项排在第一位,但它不会是第一个出现的。而根据其 orderInCategory 属性,你的操作栏左侧到右侧的搜索图标将是第一个。


easy and clear, thanks! - Greenev

3
我假设您正在将自定义视图设置为操作栏中的自定义视图。如果您使用ActionbarSherlock,可以将自定义视图添加为普通菜单项,并使用.setActionView(yourCustomView or yourCustomLayoutId) 为其设置操作视图。然后,您可以设置.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)以显示该视图。只需确保您的自定义视图宽度为wrap_content或其他宽度,否则它将将其他菜单项推出屏幕。这可能也适用于没有ActionbarSherlock的情况,但我还没有尝试过。
编辑:尝试修改您的onCreateOptionsMenu方法。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.websearch_menu, menu);

    // add this
    menu.add(Menu.NONE, 0, Menu.NONE, "custom")
        .setActionView(R.layout.header)
        .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

    return true;
}

并且从您的onCreate方法中删除此内容

actionBar.setDisplayShowCustomEnabled(true);
cView = getLayoutInflater().inflate(R.layout.header, null);
actionBar.setCustomView(cView);

编辑:

如果您需要从自定义布局引用视图,则可以在onCreateOptionsMenu方法中按以下方式执行(注意:我是在浏览器中编写此代码,因此不能保证我没有犯错或其他问题):

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // inflate the menu and add the item with id viewId,
    // which has your layout as actionview

    View actionView = menu.getItem(viewId).getActionView();
    View viewFromMyLayout = actionView.findViewById(R.id.viewFromMyLayout);

    // here you can set listeners to your view or store a reference 
    // to it somewhere, so you can use it later

    return true;
}

你太棒了,老兄。非常感谢你,你让我免于创建完整的自定义布局并将其填充到操作栏中。谢谢! - Anupam
@Thrakbad,我们能否给菜单项左侧留出一些边距,以使其完全位于操作栏的中央? - Anupam
@androiddeveloper 这些项是从左到右依次添加的,因此最后添加的项将位于右侧(溢出菜单除外)。 - Thrakbad
但是,如何解决呢?即使在header.xml文件中添加OnClick方法,应用程序仍会崩溃并显示找不到方法的错误。 - Mahdi
啊,抱歉我没有正确理解你的问题。你不能使用XML,必须在代码中实现。请参见我上面的第二个编辑。 - Thrakbad
显示剩余8条评论

2
菜单项的顺序将根据它们在所填充的XML文件中的顺序进行设置。因此,您只需要按照自己的喜好更改XML文件中的顺序即可。

0
一种实现方法是通过调用invalidateOptionMenu,并在onCreateOptionsMenu方法中按您希望放置它们的顺序放置菜单项。
顺便提一下,如果您使用ActionBarSherlock,则此方法可用,因此请忽略关于它的Lint警告。

你能指导我如何实现这个吗?任何形式的代码对我都有帮助。 - Anupam
是的,无论您想要更改项目的顺序在哪里,都要保存项目顺序的配置,并调用invalidateOptionMenu()。然后,在onCreateOptionsMenu()方法中,检查您存储的配置,并使用循环按其顺序遍历所有要插入的项目,并逐个将它们动态添加到菜单中。您应该通过访问onCreateOptionsMenu()的“menu”变量来执行此操作。如果您希望使用inflate包含“静态”操作项,那么可以,只需找到确切的位置放置其余部分即可。 - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接