简体   繁体   中英

How do I remove a menu item on the fly?

My Android app has a navigation drawer with a menu. 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. 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:

// 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? 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

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

    And then override your menu file without action_acc_upgrade item for paid flavour.

  2. If you want change visibility programmatically, try to use onPrepareOptionsMenu instead of 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() .

If it's on the fly , you need to override onPrepareOptionsMenu and call invalidateOptionsMenu if applicable:

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

See 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:

@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() .

You can do it in onCreate() of your activity:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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