如何强制执行onPrepareOptionsMenu方法?

9
在我的活动的onCreateOptionsMenu方法中,我只是导入我的菜单布局文件并附加它。
我想要根据全局变量的值显示/隐藏一些菜单项,在onPrepareOptionsMenu方法中完成。我已经阅读到这是正确的做法。
我的onPrepareOptionsMenu方法不总是会触发。我不知道为什么,但当我按下手机上的“菜单”按钮时,它并不总是会触发。也许它与它的内部状态有关。
似乎在创建Activity时会触发它。第一次按下“菜单”按钮不会使其触发,但如果我第二次按下菜单按钮,它就能正常工作。
有没有办法强制onPrepareOptionsMenu触发?
感谢。
Smok建议使用invalidateOptionsMenu方法来使菜单项失效,但这会导致onCreateOptionsMenu方法也触发。以下是我的方法:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    System.out.println("onCreate");

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconified(false);
    searchView.requestFocusFromTouch();

    return true;

}

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    System.out.println("prepared");

    if (this.objAdapter == null) {
        menu.findItem(R.id.sort).setVisible(false);
        menu.findItem(R.id.filter).setVisible(false);
        menu.findItem(R.id.group).setVisible(false);
    } else {
        menu.findItem(R.id.sort).setVisible(true);
        menu.findItem(R.id.filter).setVisible(true);
        menu.findItem(R.id.group).setVisible(true);

    }

    return true;
}

从我的onCreateOptionsMenu方法中可以看出,再次调用它将导致焦点丢失到SearchView


1
你是否正在使用ActionBar?请查看这个答案 - smok
嗨Smok,我已经尝试过了,它确实起作用,但会导致额外的复杂性。这也会导致我的onCreateOptionMenu方法出现某些原因而被触发。我正在此方法中实例化我的SearchView并将焦点设置为SearchView,以便用户可以开始搜索。如果需要invalidateOptionsMenu来引发onPrepareOptionsMenu,则onCreateOptionsMenu也会被触发,焦点会回到SearchView。似乎是一个进退两难的局面。还有其他建议吗? - Mridang Agarwalla
3个回答

24

正如Smok指出的那样:通过调用invalidateOptionsMenu()


3

我遇到了同样的问题,并通过supportInvalidateOptionsMenu()方法进行了修复(因为我使用的是支持Activity),但需要一个解决方法。

我有一个标志变量,在onCreateOptionsMenu(Menu menu)方法中以以下方式进行检查:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (!IS_MENU_FIXED) {
        // Create menu only the first time the activity is loaded
        super.onCreateOptionsMenu(menu);
        getSupportMenuInflater().inflate(R.menu.main, menu);
        // Create menu items, etc...
    }
    return true;
}

当需要时,我这样调用supportInvalidateOptionsMenu():

if (!IS_MENU_FIXED) {
    supportInvalidateOptionsMenu();
    IS_MENU_FIXED = Boolean.TRUE;
}

这是与此主题相关的官方文档
谢谢,Gabriel。

0

我在一个NavigationDrawer Activity中使用这段代码,其中包含两个嵌套的Fragment(FullCoinsFragment和NewsFragment):

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.navigation, menu);

    MenuItem item = menu.findItem(R.id.action_search); //i will remove it later
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
    searchView.setOnQueryTextListener(this);

    return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    FullCoinsFragment test = (FullCoinsFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_COINS);
    if (test != null && test.isVisible()) return true; // i don't want to show this menu search in NewsFragment
    menu.removeItem(R.id.action_search); //i'm removing the search option
    return true;
}

在我的NewsFragment的onCreate()方法中,我有以下代码:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_news, container, false);

    //views initialization

    getActivity().invalidateOptionsMenu(); //i'm forcing the call to onCreateOptionsMenu() and onPrepareOptionsMenu

    return view;
}

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