the_gesslar
the_gesslar

Reputation: 387

Trying to hide a menuitem in Android, not behaving as expected

I have the below menu item created and is showing always as an action, instead of being hidden in an overflow menu.

<item android:id="@+id/menu_refresh_network"
    android:orderInCategory="100"
    android:icon="@drawable/ic_menu_action_refresh_network"
    android:title="@string/title_refresh_network"
    android:enabled="true"
    app:showAsAction="always" />

I need it to be hidden when ThreshVoteIntentService.mOpportunistic is TRUE. I have a receiver which is alerted by intent when that value has changed. It's a very simple procedure that invalidates the menu.

IntentFilter filterModeUpdated = new IntentFilter(resources.getString(R.string.action_mode_updated));
mModeUpdatedReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        invalidateOptionsMenu();
    }
};

this.registerReceiver(mModeUpdatedReceiver, filterModeUpdated);

I have my options menu then (supposedly) redraw in onPrepareOptionsMenu.

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    menu.findItem(R.id.menu_refresh_network).setVisible(ThreshVoteIntentService.mOpportunistic);

    return super.onPrepareOptionsMenu(menu);
}

What actually happens is that the visibility of menu_refresh_network only changes when I open the overflow menu. Have I basically misunderstood how this should work?

Upvotes: 1

Views: 1082

Answers (2)

Doug Stevenson
Doug Stevenson

Reputation: 317372

onPrepareOptionsMenu() is only called, as you say, just before the overflow menu is show, so that's too late.

You need to call setVisible(false) on the correct MenuItem before invalidating the options menu. So in your onCreateOptionsMenu(), find a reference to the MenuItem with findItem() for the item id that you want to change and store that in a member variable. Then, when the broadcast arrives, change the visibility of that item and then invalidate the options menu.

Here is a sample activity based off a new project I created in Android Studio to demonstrate this. If you run this, you can see that the menu item disappears after 5 seconds, and no invalidate is even required to force the menu to refresh.

public class MainActivity extends AppCompatActivity {

    private MenuItem menuItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Hide the menu item in 5 seconds
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                menuItem.setVisible(false);
            }
        }, 5000);
    }

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

        menuItem = menu.findItem(R.id.action_settings);
        MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);

        return true;
    }

}

Upvotes: 2

ianhanniballake
ianhanniballake

Reputation: 199805

If you are using AppCompatActivity (as app:showAsAction implies), you should use supportInvalidateOptionsMenu() in place of invalidateOptionsMenu() as invalidateOptionsMenu() does not know about always visible action items (hence, why it only calls onPrepareOptionsMenu() when the menu is opened)

Upvotes: 0

Related Questions