Style action bar items differently whether contextual mode is on or not?

547 views Asked by At

My use case is this: the default action bar displays a blueish background and I want the buttons to turn green on press; on the other hand, the contextual action bar is green and I want the button to turn blue on press. (sort of inverse colours)

  • Default action bar: blue background, green overlay (pressed state)
  • Contextual action mode: green background, blue overlay (pressed state)

I have already the selectors, and I can set android:actionBarItemBackground in my theme to set the drawable for both modes. I can also style the close button setting a style in android:actionModeCloseButtonStyle and it works fine.

How can I style the other buttons then?

Thanks all, Gil

1

There are 1 answers

3
user On BEST ANSWER

As I said in my comment, the views of the MenuItems weren't made accessible so you don't have any direct options to access them. One way to alternate the selector for those MenuItems is to use MenuItems with action views set to ImageViews to hold the normal icon and change the selector for those ImageViews. An example below:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/menuFirst"
    android:showAsAction="always"
    android:actionLayout="@layout/image_menu_layout"/>
</menu>

<!-- image_menu_layout.xml -->
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent" 
       style="@style/Widget.ActionButton"/>

The code for the ActionBar part:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.your_menu, menu);
    // call this for any menu item that you might have
    setUpMenuItem(menu, R.id.menuFirst, false, null);
    return super.onCreateOptionsMenu(menu);
}

/**
 * This methods set up the MenuItems.
 * 
 * @param menu the menu reference, this would refer either to the menu of the ActionBar or 
 *             the menu of the ActionMode
 * @param itemId the id of the MenuItem which needs work
 * @param onActionMode flag to indicate if we're working on the ActionBar or ActionMode
 * @param modeRef the ActionMode reference(only when the MenuItem belongs to the ActionMode, 
 *                null otherwise)
 */
private void setUpMenuItem(Menu menu, int itemId, final boolean onActionMode,
                           final ActionMode modeRef) {
    final MenuItem menuItem = menu.findItem(itemId);
    ImageView itemLayout = (ImageView) menuItem.getActionView();
    itemLayout.setBackgroundResource(onActionMode ? R.drawable.selector_for_actionmode : R
            .drawable.selector_for_actionbar);
    itemLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // for simplicity, wire up the normal selection callbacks(if possible, 
            // meaning the Activity implements the ActionMode.Callback)
            if (onActionMode) {
                onActionItemClicked(modeRef, menuItem);
            } else {
                onOptionsItemSelected(menuItem);
            }
        }
    });
}

The code for the ActionMode part:

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    getMenuInflater().inflate(R.menu.actiomode_menu, menu);
    // call this for any menu item that you might have
    setUpMenuItem(menu, R.id.menu_item_from_actionmode, true, mode);
    return true;
} 

This method will also allow you to avoid the need to handle/keeping the status of the ActionBar/ActionMode while the Activity is used.