Android操作栏不显示溢出


90

我的应用程序中有一个包含3个项目的操作栏。

由于空间问题,只能显示2个,因此我希望第一个显示,其余的显示在溢出中。但是实际上,仅显示前2个项目,并且没有可检测到的溢出。

以下是相关代码:list_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_insert"
    android:icon="@android:drawable/ic_menu_add"
    android:title="@string/menu_insert" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_call"
    android:icon="@android:drawable/ic_menu_call"
    android:title="@string/menu_call" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_agenda"
    android:icon="@android:drawable/ic_menu_agenda"
    android:title="@string/menu_agenda" 
    android:showAsAction="ifRoom|withText"/>
</menu>

Activity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater mi = getMenuInflater();
    mi.inflate(R.menu.list_menu, menu);
    return true;
}

120
如果您的设备具有菜单按钮,则不会显示溢出图标。您正在使用什么设备?
Reinier 2012年

1
我正在测试的虚拟设备确实具有菜单按钮,单击它,然后显示缺少的项目,谢谢!
Mats Raemen'3

2
@Reinier我正在使用ActionBarSherlock。在运行2.3的Galaxy Ace上显示,在运行4.0的Galaxy SII上未显示。两者都有硬件菜单按钮。
史密斯先生2012年

2
我想确认这让我感到困惑,因为我在nexus 7购买(而不是Galaxy Note II)上安装了溢出图标。注意有一个菜单按钮。谢谢!
bsautner

@Reinier请帮助我面对同样的问题我该怎么办?
rupesh 2013年

Answers:


125

如果要显示三个点,则与设备菜单按钮无关!那么您可以在应用程序类的onCreate方法中调用此方法-

private void makeActionOverflowMenuShown() {
    //devices with hardware menu button (e.g. Samsung Note) don't show action overflow menu
    try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if (menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage());
    }
}

32
这是一个可怕的骇客,破坏了与平台上其他应用程序的一致性。不要这样做。
adamp

19
这似乎有两个弊端。当前的行为是不可接受的。
biorbnA 2013年

6
这是允许溢出的好方法,菜单硬键将不再被允许。
Necronet

5
效果很好!即使用户按下硬件菜单按钮(效果非常出色)也可以使用,尽管您会听到两次菜单声音效果。
2013年

5
这不是问题。开发人员需要知道该如何称呼骇客,因为在Android中它不是2 + 2。反射使用Java机制节省了时间,否则您将把上下文传递给内部类24/7,或者将AOSP定制为无穷大。对我而言,此解决方案解决了仅出于纯粹主义者认为干净的原因而必须覆盖并包含大量AOSP自定义内容和链接的私人协会的问题。您知道吗?您不能为小型列表强制一致地启用FASTSCROLL吗?在使用反射之前,这需要我复制10多个AOSP资源,以进行一个字符编辑。
leRobot 2014年

54

动作栏

res / menu / menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- Search / will display always -->
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="always"
        android:title="@string/action_search"/>

    <!-- Location Found -->
    <item
        android:id="@+id/action_location_found"
        android:icon="@drawable/ic_action_location_found"
        android:showAsAction="always"
        android:title="@string/action_location_found"/>

    <!-- More -->
    <item
        android:id="@+id/a_More"
        android:icon="@drawable/ic_action_overflow"
        android:showAsAction="always"
        android:title="More">
        <menu>

            <!-- Refresh -->
            <item
                android:id="@+id/action_refresh"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_refresh"/>

            <!-- Help -->
            <item
                android:id="@+id/action_help"
                android:icon="@drawable/ic_action_help"
                android:showAsAction="never"
                android:title="@string/action_help"/>

            <!-- Check updates -->
            <item
                android:id="@+id/action_check_updates"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_check_updates"/>
        </menu>
    </item>

</menu>

MainActivity.java

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

}

下载操作栏图标集


2
看一下@Reinier注释,它的确是“如果您的设备具有菜单按钮,则不会显示溢出图标”。
Ahmad Dwaik'Warlock'13

我在具有菜单按钮的设备中进行测试,在我的情况下显示溢出。我使用android:showAsAction="always"更多物品
Kirit Vaghela

您在什么设备上测试过?我使用了neo v xperia和s#
Ahmad Dwaik'Warlock'13

1
注意:会使您的溢出菜单膨胀的项目务必showAsAction =“ always”
Kirit Vaghela 2013年

1
在旧版SDK的android名称空间中,showAsAction不可用。请点击以下链接developer.android.com/training/basics/actionbar/…来解决这个问题。添加此NS schemas.android.com/apk/res-auto之后,上述技巧对我来说就很好了
chedine 2014年

42

我意识到这不是一个溢出菜单,但它是相似的。好的,这很简单,但是很难弄清楚。

首先,您需要一个要用作溢流充气机的菜单项。例

<item
        android:id="@+id/a_More"
        android:icon="@drawable/more"
        android:showAsAction="always"
        android:title="More">
        </item>

拥有商品后,在溢出菜单中添加一个包含所需商品的子菜单。例:

<item
    android:id="@+id/a_More"
    android:icon="@drawable/more"
    android:showAsAction="always"
    android:title="More">
    <menu>
        <item
            android:id="@+id/aM_Home"
            android:icon="@drawable/home"
            android:title="Home"/>
    </menu>
</item>

在单击时,这将使其中的其他项目膨胀。我的应用程序使用的是ActionBarSherlock 4.0,因此在此之前,您需要访问“ SplitActionBar”。(仍将在默认的Android Actionbar上运行)

方法如下:在您的AndroidManifest.xml文件中,您需要在需要溢出菜单的活动下添加此代码。

android:uiOptions="splitActionBarWhenNarrow"

注意:必须使溢出菜单膨胀的项showAsAction="always"

哇!您有一个溢出菜单!希望我能帮到你。:)


3
不错的解决方案,比菜单按钮破解更好。
ol0

26

在带有硬件菜单按钮的设备(Galaxy S3,像三星一样固执...)上,溢出菜单通过使用硬件菜单按钮充当“传统”菜单。


2
旧的答案,但是兼容性库只是偶然发现非常奇怪的结果:3个带有硬件按钮的设备,注3 Neo =显示了溢出菜单,菜单按钮不起作用,注1 =没有溢出,菜单按钮起作用,Galaxy S3,否溢出,菜单按钮不起作用!这太疯狂了。
2014年

5

当您说“溢出”菜单时,是指最后出现的三个点表示还有更多项目....还是意味着出现在底部的有溢出项目的拆分操作栏?

如果您是指拆分操作栏,则应将其添加到活动的清单文件中

android:uiOptions="splitActionBarWhenNarrow"

默认情况下,三点溢出菜单应自动发生,因此很难从上面提供的信息中分辨出问题所在。


我的意思是三个点。它不喜欢它是因为项目的,因为每当改变顺序的项目,它是显示第2个图标
垫Raemen

我应该提供额外的信息来确定实际问题吗?
Mats Raemen'3

您的minSdkVersion,targetSdkVersion和正在测试的版本是什么?
闪亮

5
您的设备是否具有用于菜单的物理按钮,或者它们是像银河系手机一样的虚拟按钮?我认为这三个点只会在您的手机没有物理按钮的情况下显示。
wnafee 2012年

5

要始终
在菜单文件中的actionbarcompat:上显示动作溢出(三个点),例如:
main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_about"
        android:title="@string/action_about"
        app:showAsAction="never"/>

</menu>

在活动文件中:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
}

对我来说很好。
在Google Nexus S和Samsung S3上进行了测试。


3

看来在带有菜单按钮的设备上,溢出菜单不会显示在ActionBar中。同样,我们也无法知道设备 API级别14 之前是否具有硬件菜单按钮(4.0+)。

此解决方案在上添加了一个溢出按钮,该按钮仅android.support.v7.app.ActionBar打开蜂窝前(<3.0)上的标准选项菜单,否则将其留给系统。在任何情况下,你可以选择alwaysifRoom进行的所有操作。

操作栏图标包中获取溢出图标。

添加菜单(我将一些不相关的部分省略为标题,订购等)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

<item
    android:id="@+id/action_overflow"
    android:orderInCategory="100"
    android:icon="@drawable/ic_action_overflow"
    app:showAsAction="always" />

<item
    android:id="@+id/action_first"
    app:showAsAction="always" />

<item
    android:id="@+id/action_second"
    app:showAsAction="ifRoom" />

</menu>

在3.0+上删除我们的溢出操作

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        menu.removeItem(R.id.action_overflow);
    }
    return super.onPrepareOptionsMenu(menu);
}

最后Activity.openOptionsMenu()从溢出动作调用。

呃没有。您不能通过openOptionsMenu()菜单按钮进行调用...但是,如果您使用的是AndroidAnnotations,则可以轻松完成:

@OptionsItem
void action_overflow() {
    openOptionsMenuDeferred();
}

@UiThread
void openOptionsMenuDeferred() {
    openOptionsMenu();
}

我想如果不是这样的话

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == id.action_overflow) {
        openOptionsMenuDeferred();
        return true;
    }
}

private Handler handler = new Handler(Looper.getMainLooper());
public void openOptionsMenuDeferred() {
    handler.post(new Runnable() {
        @Override
        public void run() {
            openOptionsMenu();
        }
    }
    );
}


2

放入xmlns:your_app_name="http://schemas.android.com/apk/res-auto"菜单标签内,改为android:showAsAction="always"使用your_app_name:showAsAction="always"

例如

<item
    android:id="@+id/action_search"
    android:icon="@drawable/icon_search"
    android:title="@string/search"
    your_app_name:showAsAction="ifRoom"/>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.