Search code examples
androidcheckboxswitch-statementoncreateoptionsmenu

How do you get a switch statement in android to recognize a checkbox?


I would like to clean up my code and have my checkbox do some actions from the switch statement inside onOptionsItemSelected(). Instead, I have an onClick listener in onCreateOptionsMenu for my custom checkbox. This works, but I would like to understand how to have code inside case R.id.star_favorite: called.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    checkBox = (CheckBox) menu.findItem(R.id.star_favorite).getActionView();
    checkBox.setButtonDrawable(R.drawable.favorite_checkbox);
    if(currentQuote != null) {
        currentQuoteIsFavorite = currentQuote.getFavorite();
        checkBox.setChecked(currentQuoteIsFavorite);
    }
    checkBox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(currentQuote != null) {
                currentQuoteIsFavorite = !currentQuoteIsFavorite;
                updateFavorite(currentQuoteIsFavorite);
            } else {
                checkBox.setChecked(false);
                Toast.makeText(getApplicationContext(), "No Quote To Save", Toast.LENGTH_SHORT).show();
            }
        }
    });
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
        case R.id.star_favorite:
            //already tried putting code like updateFavorite() inside here but it's not called
            Toast.makeText(this, "Checkbox clicked", Toast.LENGTH_SHORT).show();
            if(currentQuote != null) {
                currentQuoteIsFavorite = !currentQuoteIsFavorite;
                updateFavorite(currentQuoteIsFavorite);
            } else {
                checkBox.setChecked(false);
                Toast.makeText(getApplicationContext(), "No Quote To Save", Toast.LENGTH_SHORT).show();
            }
        case R.id.share_quote:
            Log.d("onOptionsItemSelected", "case R.id.share_quote selected");
            shareQuote();
            break;
        case R.id.menu:
            Log.d("onOptionsItemSelected", "case R.id.menu selected");

            break;
    }
    return super.onOptionsItemSelected(item);
}

Solution

  • In this case, you don't need a Checkbox at all. You can use the android:checkable attribute to make a menu item checkable. You then update the icon in onOptionsItemSelected().

    QuoteActivity.java

    public class QuoteActivity extends AppCompatActivity {
    
        // saved state, randomized for testing
        private Random rand = new Random();
        private boolean savedAsFavorite = rand.nextBoolean();
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.quote_activity);
            setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.quote_menu, menu);
            toggleItem(menu.findItem(R.id.favorite), savedAsFavorite);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.favorite:
                    toggleItem(item, !item.isChecked());
                    return true;
                case R.id.share:
                    // do something
                    return true;
            }
            return super.onOptionsItemSelected(item);
        }
    
        private void toggleItem(MenuItem item, boolean isChecked) {
            item.setChecked(isChecked);
            item.setIcon(iconDrawable(isChecked));
        }
    
        private Drawable iconDrawable(boolean isChecked) {
            return getDrawable(isChecked ? R.drawable.favorite_enabled : R.drawable.favorite_disabled);
        }
    }
    

    quote_menu.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <item
            android:id="@+id/favorite"
            android:icon="@drawable/favorite_disabled"
            android:title="Favorite"
            app:showAsAction="ifRoom"
            android:checkable="true"
            android:checked="false"/>
    
        <!-- additional menu items -->
    
    </menu>
    

    And of course, you need two drawables for the enabled and disabled state of the favorite icon. Hope that helps!