【问题标题】:Change options menu during runtime - invalidateOptionsMenu()在运行时更改选项菜单 - invalidateOptionsMenu()
【发布时间】:2012-10-22 04:31:52
【问题描述】:

我正在创建一个菜单,其中一个项目用于锁定对象。单击此项目时,应使用按钮重新创建菜单以解锁该项目。我为此创建了两个菜单。这工作正常。我读到在 Android 版本 >= 11 中,在显示菜单时不再调用 onPrepareOptionsMenu,我必须调用 invalidateOptionsMenu()。所以我将构建目标(在清单和属性中)更改为 11,并在 4.0.3 的 AVD 上运行应用程序。该程序仍然运行良好,但我认为它不应该了,我应该检查一下

if (Build.VERSION.SDK_INT >= 11)
{
  invalidateOptionsMenu();
}

这是我的代码:

public class MainActivity3 extends Activity{

    boolean locked;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        locked = false;
    }

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

            return true;
        }

        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {

            menu.clear();
            MenuInflater inflater = getMenuInflater();

            if (locked) {
                inflater.inflate(R.menu.changing_menu2, menu);
            }
            else {
                inflater.inflate(R.menu.changing_menu1, menu);
            }

        return super.onPrepareOptionsMenu(menu);
        }

        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {

          case R.id.Menu1:
          break;

          case R.id.Menu2 :
          break;

          case R.id.Menu3 :
          locked = !locked;
          break;

           }
        return true;
        }
}

所以菜单在 4.0 中仍然刷新/重新创建。 我对 invalidateOptionsMenu(); 的用法有误解吗?

【问题讨论】:

  • 我不知道如何举报,但即使是android开发人员也不清楚这一点。在这里检查:developer.android.com/guide/topics/ui/… 如果您只阅读此内容,您将了解 invalidateOptionsMenu() 不会调用 onCreateOptionsMenu() 并且在 Android >= 11 OnPrepareOptionsMenu() 每次打开菜单时都不起作用...但确实如此.哎呀?很好的问题erdomester和很好的答案@justinmorris

标签: android menu


【解决方案1】:

添加invalidateOptionsMenu() 是为了让我们能够强制再次调用onCreateOptionsMenu()。每次调用菜单时仍会调用onPrepareOptionsMenu()

您在上面尝试实现的目标是何时使用 invalidateOptionsMenu() 的一个很好的示例,但由于向后兼容,您需要同时执行这两个操作:

if (Build.VERSION.SDK_INT >= 11) {
  invalidateOptionsMenu();
}


@Override
public boolean onCreateOptionsMenu(Menu menu){
    if (Build.VERSION.SDK_INT >= 11) {
        selectMenu(menu);
    }
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT < 11) {
        selectMenu(menu);
    }
    return true;
}

private void selectMenu(Menu menu) {
    menu.clear();
    MenuInflater inflater = getMenuInflater();

    if (locked) {
        inflater.inflate(R.menu.changing_menu2, menu);
    }
    else {
        inflater.inflate(R.menu.changing_menu1, menu);
    }
}

【讨论】:

  • 嗨!这看起来不错!但我看不到 invalidateOptionsMenu() 在这里做了什么。首先,调用 onCreateOptionsMenu。如果 API >= 11,则调用 selectMenu(),但如果 API = 11), onPrepareOptionsMenu 是系统自动调用的,但是只有在 API
  • 在您的用例中使用 invalidateOptionsMenu() 无非是一个微小的性能改进。最终,仅在“锁定”更改时才在较新的设备上调用 invalidateOptionsMenu() 更有效。然后 11+ 设备只会在有理由时膨胀新的选项菜单,但旧设备会在用户每次点击菜单按钮时重新膨胀选项菜单。通过使用布尔开关并在 onPrepareOptionsMenu() 中检查它以查看是否需要重新扩展菜单,您可以获得相同的性能增强,但向后兼容。
  • 所以基本上我什至不必调用 invalidateOptionsMenu()。对于 API > 11 的设备,这只是一种安全方法,对吧?而且,在您的代码中,仅当 API
  • 正确,您不需要调用 invalidateOptionsMenu().. 我只是向您展示了如何做到这一点。在我的代码中,如果 API
  • 另一种选择是使用一个菜单 xml 并有组。可以在 onPrepareOptionsMenu() 中更改组的可见性
猜你喜欢
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多