4

当 Galaxy S3 上没有打算在操作栏中的溢出菜单中显示的操作时,我遇到了问题。因此,用户体验有些混乱——我在 Galaxy S3 上的操作栏只显示应用程序徽标和名称,但不提供额外功能。

我希望在运行 Android 4.x 的所有设备上拥有相同的 UX,并在溢出菜单中执行操作。如果不使用 ActionBarSherlock 等第三方组件,这是否可行?

坦尔斯

4

2 回答 2

2

有一种快速而肮脏的方法可以使用反射在应用程序ViewConfiguration实例中设置字段来伪造硬件菜单按钮的缺失。

以下代码片段可以添加到您的活动中并在onCreate().

private void enableActionBarOverflow() {
    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) {
        e.printStackTrace();
    }
}

不是一个干净的解决方案,因为 ViewConfiguration 的实现可能会在未来的某个时候发生变化,并且由于该sHasPermanentMenuKey字段是私有的,因此不能保证该字段将始终存在。

但是,如果您绝对必须在具有菜单键的设备上使用溢出菜单,我只会将其用作最后的手段。

假设您的最低 API 为 11(Honeycomb)或更高,更好的解决方案是制作您自己的溢出菜单,如下所示:

  1. 在 menu.xml 中为溢出添加一个菜单项,将其设置为始终显示并在您的onCreateOptionsMenu()

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        ...
        <item
            android:id="@+id/action_overflow"
            android:icon="@drawable/ic_action_settings"
            android:title="@string/settings"
            android:showAsAction="always">
        </item>
    </menu>
    

    ,

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater mi = getMenuInflater();
            mi.inflate(R.menu.menu, menu);
            return super.onCreateOptionsMenu(menu);
    }
    
  2. 在溢出菜单中为您想要的选择创建一个单独的overflow_menu.xml 资源

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <item
            android:id="@+id/overflow_action1"
            android:title="@string/overflow_action1">
        </item>
        <item
            android:id="@+id/overflow_action2"
            android:title="@string/overflow_action2">
        </item>
    </menu>
    
  3. 在您的onOptionsItemSelected()方法中,处理溢出菜单的选择

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            ...
            case R.id.action_overflow:
                    PopupMenu popup = new PopupMenu(
                            this, findViewById(R.id.action_overflow));
                    MenuInflater inflater = popup.getMenuInflater();
                    inflater.inflate(R.menu.overflow_menu, popup.getMenu());
                    popup.setOnMenuItemClickListener(this);
                    popup.show();
                    return true;
            default:
                    return super.onOptionsItemSelected(item);
            }
    }
    
  4. 在您的活动中实现PopupMenu.OnMenuItemClickListener接口以处理溢出项的点击

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.overflow_action1:
            //do stuff
            return true;
        case R.id.overflow_action2:
            //do stuff
            return true;
        default:
            return false;
        }
    }
    
于 2013-12-04T21:05:06.077 回答
2

这是一些制造商做出的决定,如果你真的想这样做,就需要一些“坏”的解决方案。溢出菜单只是所有 android 设备曾经拥有的“常规”旧菜单按钮。当 Google 在 Honeycomb 和 ICS 中删除菜单按钮时,一些制造商决定保留菜单按钮。这导致人们对菜单按钮是什么以及做什么感到非常困惑。

您应该记住,尽管使用 S3 的用户希望有一个功能菜单按钮,因为他们不习惯看到 3 点菜单。所有使用内置菜单系统的应用程序都应该以他们期望的方式呈现给用户。因此,在这件事上,我强烈建议不要让你的应用在所有设备上看起来完全相同,因为这很可能会让用户感到困惑,而不是帮助他们。但是,如果您愿意,应该可以同时实现“正确的”菜单系统和“自定义/假”的 3 点菜单。

这篇文章似乎有一些很好的指导方针: https ://stackoverflow.com/a/10713860/1068167

于 2012-12-20T08:23:34.483 回答