【问题标题】:Android action bar not showing overflowAndroid操作栏不显示溢出
【发布时间】:2012-03-16 14:51:27
【问题描述】:

我的应用中有一个包含 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;
}

【问题讨论】:

  • 如果您的设备有菜单按钮,溢出图标将不会显示。你在什么设备上?
  • 我正在测试的虚拟设备确实有一个菜单按钮,单击它并显示缺少的项目,谢谢!
  • @Reinier 我正在使用 ActionBarSherlock。在运行 2.3 的 Galaxy Ace 上显示,在运行 4.0 的 Galaxy SII 上不显示。两者都有硬件菜单按钮。
  • 我想确认这让我感到困惑的是,我在 nexus 7 上购买了溢出图标,而不是在 Galaxy Note II 上。 Note 有一个菜单按钮。谢谢!
  • @Reinier 请帮助我面临同样的问题我该怎么办?

标签: android overflow android-actionbar


【解决方案1】:

如果你想显示三个点,不管设备菜单按钮是什么!然后你可以在你的应用程序类的 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());
    }
}

【讨论】:

  • 这是一个糟糕的 hack,它破坏了与平台上其他应用程序的一致性。不要这样做。
  • 这似乎是两害相权取其轻。当前的行为是不可接受的。
  • 这是允许溢出的好方法,不应再容忍菜单硬键。
  • 效果很好!即使用户按下硬件菜单按钮(这很棒)也可以工作,尽管您会听到两次菜单音效.. 有谁知道如何让它只发出一次声音?
  • 这不是黑客攻击。开发人员需要知道什么叫做 hack,因为它在 Android 中不是 2+2。反射正在使用 Java 机制节省时间,否则您将 24/7 将上下文传递给您的内部类,或者将 AOSP 自定义为无穷大。对我来说,这个解决方案解决了为了纯粹主义者认为干净而必须覆盖和包含大量 AOSP 自定义内容和链接的私人关联的问题。您是否知道您不能强制为小列表始终启用 FASTSCROLL?在我使用反射之前,这需要我复制 10 多个 AOSP 资源,以进行 ONE 字符编辑。
【解决方案2】:

输出

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

}

下载Action Bar Icon Set

【讨论】:

  • 看看@Reinier 的评论,确实是“如果您的设备有菜单按钮,溢出图标将不会显示”。
  • 我在具有菜单按钮的设备中进行测试,并且在我的情况下显示溢出。我使用android:showAsAction="always" 获取更多项目
  • 你在什么设备上测试过它?我用过 neo v xperia 和 s#
  • 注意:让溢出菜单膨胀的项目必须 showAsAction="always"
  • showAsAction 在旧版 SDK 的 android 命名空间中不可用。按照这个链接developer.android.com/training/basics/actionbar/… 来克服这个问题。添加此 NS schemas.android.com/apk/res-auto 后,上述技巧对我来说非常有效
【解决方案3】:

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

您首先需要一个要用作溢出充气器的菜单项。示例

<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 文件中,您需要在需要溢出菜单的 Activity 下添加此代码。

android:uiOptions="splitActionBarWhenNarrow"

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

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

【讨论】:

  • 不错的解决方案,比菜单按钮破解更好。
【解决方案4】:

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

【讨论】:

  • 旧答案,但是使用兼容性库时偶然发现了非常奇怪的结果:3 个带有硬件按钮的设备,注 3 Neo = 显示溢出菜单,菜单按钮不起作用,注 1 = 无溢出,菜单按钮有效,Galaxy S3,没有溢出,菜单按钮无效!这太疯狂了。
【解决方案5】:

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

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

android:uiOptions="splitActionBarWhenNarrow"

默认情况下,三点溢出菜单应该是自动出现的,所以从你上面提供的信息很难判断问题出在哪里。

【讨论】:

  • 我的意思是三个点。这不是因为商品,因为每当更改订单商品时,都会显示前 2 个图标
  • 我应该提供额外的信息来确定实际问题吗?
  • 你的 minSdkVersion、targetSdkVersion 是什么,你正在测试的版本是什么?
  • 您的设备是否有用于菜单的物理按钮,或者它们是否像 Galaxy nexus 手机一样是虚拟按钮?我认为这三个点只有在您的手机没有物理按钮时才会出现。
【解决方案6】:

在 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、三星 S3 上测试。

【讨论】:

    【解决方案7】:

    在带有菜单按钮的设备上,溢出菜单似乎不会显示在操作栏中。我们也无法知道设备是否有硬件菜单按钮之前 API level 14 (4.0+)。

    此解决方案向android.support.v7.app.ActionBar 添加了一个溢出按钮,该按钮仅在预Honeycomb (always 或ifRoom 之间选择所有操作。

    Action Bar Icon Pack 获取溢出图标。

    添加一个菜单(我省略了一些不相关的部分,如标题、排序等)

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

    【讨论】:

      【解决方案8】:

      尝试将应用的主题从 Theme.AppCompat.Light.DarkActionBar 到 Theme.AppCompat.Light

      【讨论】:

        【解决方案9】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多