使用invalidateOptionsMenu()的动态选项菜单

时间:2013-06-26 15:50:59

标签: android android-optionsmenu

我正在开发一款游戏,在实施Google Play游戏服务后我发现自己需要动态选项菜单。我的整个游戏包括strings.xml和6个活动(不包括导入的库项目)。我之所以提到这一点,只是因为这意味着我在不使用layout.xml的情况下构建选项菜单。

我要完成的是根据用户登录状态更改登录和注销按钮的可见状态。目前,当用户登录菜单时,正确更新自身并且“登录”按钮被“注销”替换。但是,当单击“注销”按钮时,虽然它确实正确地将用户签名,但它不会触发菜单更新。尝试通过按钮再次注销会导致应用程序崩溃,因为我没有捕获异常,我可以稍后处理。如果更改活动,菜单会正确更新。

到目前为止我看到的内容与我发现的here

非常相似

这是我的Extensions类,其他所有类都扩展为使用我游戏中常用的方法,我删除了与菜单无关的项目。

package com.domain.myapp;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Build;
import android.view.Menu;
import android.view.MenuItem;

public abstract class Extensions extends LicenseCheck {
    private static final int SOM1= 1;
    private static final int SOM2= 2;
    private static final int SOM3= 3;
    private static final int SOM4= 4;
    private static final int SOM5= 5;
    private static final int SOM6= 6;

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

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

    private void buildMenu(Menu menu) {
        menu.clear();
        menu.add(Menu.NONE, SOM1, Menu.NONE, "Instructions");
        menu.add(Menu.NONE, SOM2, Menu.NONE, "View Achievements");
        menu.add(Menu.NONE, SOM3, Menu.NONE, "View Leaderboard");
        menu.add(Menu.NONE, SOM4, Menu.NONE, "Sign In");
        menu.add(Menu.NONE, SOM5, Menu.NONE, "Sign Out");
        menu.add(Menu.NONE, SOM6, Menu.NONE, "Exit Game");
        if (isSignedIn()) {
            menu.findItem(SOM4).setVisible(false);
            menu.findItem(SOM5).setVisible(true);
        }
        if (!isSignedIn()) {
                menu.findItem(SOM4).setVisible(true);
                menu.findItem(SOM5).setVisible(false);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case SOM1:
            Intent nextInstructionScreen = new Intent(getApplicationContext(), InstructionScreen.class);
            startActivity(nextInstructionScreen);   
            break;
        case SOM2:
            viewAchievements();
            break;
        case SOM3:
            viewLeaderboards();
            break;
        case SOM4:
            beginUserInitiatedSignIn();
            break;
        case SOM5:
            getGamesClient().signOut();
            menuRefresh();
            break;
        case SOM6:
            moveTaskToBack(true);
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    @SuppressLint("NewApi")
    public void menuRefresh() {
        if (Build.VERSION.SDK_INT >= 11) {
            invalidateOptionsMenu();
        }
    }
}

此外,我花了一些时间尝试使用onSignOutComplete(),但一定是做错了。任何帮助将不胜感激。使用布尔值来跟踪登录状态也不会改变行为。当相反的功能正常工作时,我无法弄清楚为什么注销按钮在用于注销并使登录按钮可见时不会隐藏。

1 个答案:

答案 0 :(得分:0)

就个人而言,我坚持只使用onCreateOptionsMenu()并删除onPrepareOptionsMenu()方法。

每次显示菜单时都会调用<onPrepareOptionsMenu(),而onCreateOptionsMenu()仅在最初创建菜单时以及手动调用invalidateOptionsMenu()时调用。

此外,我不是先添加两个菜单项,然后删除/隐藏其中一个菜单项,而只是检查用户是否已登录,然后添加相应的菜单。

除此之外,虽然它与您的问题无关,但您应该使用字符串资源而不是硬编码菜单项标题。检查您的res/values/strings.xml文件,然后使用Java代码中的getString(R.string.id_of_string)从那里获取字符串。

PS。我猜你的LicenseCheck课程延长了Activity