简体   繁体   English

如何即时删除菜单项?

[英]How do I remove a menu item on the fly?

My Android app has a navigation drawer with a menu. 我的Android应用程序有一个带菜单的导航抽屉。 In the free version of the app, I want to have a menu item to allow the user to Upgrade to the paid version. 在该应用程序的免费版本中,我想要一个菜单​​项,以允许用户升级到付费版本。 Obviously I don't want this in the paid version. 显然,我不希望在付费版本中使用此功能。

How do I hide the menu item in the paid version? 如何在付费版本中隐藏菜单项?

The menu looks like this: 菜单如下所示:

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android">

   <item
        android:id="@+id/action_home"
        android:icon="@drawable/btn_home"
        android:title="@string/nav_home"
        />
    <item
        android:id="@+id/action_acc_upgrade"
        android:icon="@drawable/ic_star_black"
        android:title="@string/str_acc_upgrade" />
    <item
        android:id="@+id/action_help"
        android:icon="@drawable/ic_help_black"
        android:title="@string/nav_help"
        />
</menu>

In the activity, I have: 在活动中,我有:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

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

    if(isPaid()) {
        MenuItem upgrade = menu.findItem(R.id.action_acc_upgrade);
        upgrade.setVisible(false);
    }

    return true;
}

If I run this through the debugger, it reaches the line if(isPaid()) and then evaluates it as true, so goes into the setVisible part. 如果我通过调试运行它,它到达线if(isPaid())然后计算它为真,那么进入调用setVisible部分。 The item still shows up in the menu, though. 但是,该项目仍显示在菜单中。

I also tried removing the item from the menu instead of hiding it; 我还尝试过从菜单中删除该项目,而不是隐藏它。 the debugger shows that the item is removed, but then it still shows up when the menu is displayed. 调试器显示该项目已删除,但是在显示菜单时它仍然显示。

How can I hide/remove this item? 如何隐藏/删除该物品?

Edit 编辑

I'm using a navigation drawer to hold the menu. 我正在使用导航抽屉保存菜单。 This is set up in onCreate as follows: 这是在onCreate中设置的,如下所示:

// Set up toolbar
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

// Set up navigation drawer
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
        this, drawer, toolbar, R.string.nav_drawer_open, R.string.nav_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();

I suspect that this somehow bypasses onPrepareOptionsMenu etc? 我怀疑这以某种方式绕过了onPrepareOptionsMenu等? Is there a way of adding a listener which is called when the "open navigation drawer" button is clicked? 有没有添加单击“打开导航抽屉”按钮时调用的侦听器的方法? I can only find callbacks for the drawer being opened or closed, and they're called after the drawer has moved - I need to call them before. 我只能找抽屉回调被打开或关闭,而他们是所谓的抽屉移动后 - 我需要之前给他们打电话。

There are several options: 有几种选择:

  1. The most convenient option: create 2 different productFlavours in your build.gradle file 最方便的选择:在build.gradle文件中创建2种不同的产品build.gradle

     productFlavors { free { ... } paid { ... } } 

    And then override your menu file without action_acc_upgrade item for paid flavour. 然后覆盖菜单文件中没有action_acc_upgrade项的付费风味。

  2. If you want change visibility programmatically, try to use onPrepareOptionsMenu instead of onCreateOptionsMenu : 如果要以编程方式更改可见性,请尝试使用onPrepareOptionsMenu而不是onCreateOptionsMenu

     @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); if(isPaid()) { MenuItem upgrade = menu.findItem(R.id.action_acc_upgrade); upgrade.setEnabled(false); upgrade.setVisible(false); } } 

    If you need to change your menu after creation, invoke invalidateOptionsMenu() . 如果在创建后需要更改菜单,请调用invalidateOptionsMenu()

If it's on the fly , you need to override onPrepareOptionsMenu and call invalidateOptionsMenu if applicable: 如果它是在飞行中 ,你需要重写onPrepareOptionsMenu并调用invalidateOptionsMenu (如果适用):

@Override public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    menu.findItem(R.id.action_acc_upgrade).setVisible(!isPaid());
}

See Activity.onPrepareOptionsMenu : 参见Activity.onPrepareOptionsMenu

Prepare the Screen's standard options menu to be displayed. 准备要显示的屏幕标准选项菜单。 This is called right before the menu is shown, every time it is shown. 在显示菜单之前,每次显示菜单时都会调用此方法。 You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents. 您可以使用此方法有效地启用/禁用项目,或者以其他方式动态修改内容。

You should override onPrepareOptionsMenu like this: 您应该像这样重写onPrepareOptionsMenu

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    if(isPaid()) {
       menu.findItem(R.id.action_settings).setVisible(false);
    }
}

Notice: Ensure get right value of isPaid() before onPrepareOptionsMenu callback, such as in onCreate() or onResume() . 注意:确保在onPrepareOptionsMenu回调之前获得正确的isPaid()值,例如在onCreate()onResume()

You can do it in onCreate() of your activity: 您可以在活动的onCreate()中执行此操作:

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu navMenu = navigationView.getMenu();
navMenu.removeItem(R.id.action_acc_upgrade);

replace nav_view with your NavigationView 's id. nav_view替换为NavigationView的ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM