Creating contextual action mode menus

The action bar provides the user with a set of actions; however, these actions are usually just the most commonly used. Sometimes, the context of the app changes, so the presented actions need to adjust to what is commonly used in the new context.

How to do it...

There are a few steps to implementing a contextual action bar:

  1. The first step is to implement the ActionMode.ICallback interface. This interface can either be implemented in a new, separate class or on the actual activity or fragment:
    public class MainActivity :
      AppCompatActivity, ActionMode.ICallback {
      public bool OnCreateActionMode(
        ActionMode mode, IMenu menu) {
      }
      public bool OnPrepareActionMode(
        ActionMode mode, IMenu menu) {
      }
      public bool OnActionItemClicked(
        ActionMode mode,IMenuItem item) {
      }
      public void OnDestroyActionMode(ActionMode mode) {
      }
    }
  2. In the OnCreateActionMode() method, we create the menu as we would any options menu:
    public bool OnCreateActionMode(ActionMode mode, IMenu menu) {
      mode.MenuInflater.Inflate(Resource.Menu.options, menu);
      return true;
    }
  3. Because we are not going to be updating the action mode once displayed, we can return false in the OnPrepareActionMode() method:
    public bool OnPrepareActionMode(
      ActionMode mode, IMenu menu) {
      return false;
    }
  4. We handle any item selections in the OnActionItemClicked() method:
    public bool OnActionItemClicked(
      ActionMode mode,IMenuItem item) {
      if (item.ItemId == Resource.Id.action_refresh) {
        // do something here...
        return true;
      }
      return false;
    }
  5. We don't need to do anything when we leave action mode, so we leave the OnDestroyActionMode() method empty:
    public void OnDestroyActionMode(ActionMode mode) {
    }
  6. An instance of ActionMode.ICallback is passed to the StartSupportActionMode() or StartActionMode() methods:
    someView.LongClick += (sender, e) => {
      if (actionMode == null) {
        // start the action mode
        actionMode = StartSupportActionMode(this);
        someView.Selected = true;
      }
    };

How it works...

The contextual action mode menu is actually a separate action bar-like UI element that overlays but does not replace the actual action bar.

Tip

Contextual menu items do not need to have the showAsAction attribute set in order to be displayed (it is ignored); by default, everything is visible.

This menu provides a set of commands that can be displayed based on some context, usually after a selection of an item on the screen. Selections are usually done after a long-tap, similar to traditional context menus; however, instead of a popup, the action bar is transformed. This provides a consistent interface without disrupting the flow of the task.

In order to enter action mode, we invoke the StartSupportActionMode() method. If we are not using the support libraries, we invoke the StartActionMode() method. This will return an ActionMode instance, which can then be used to customize the appearance of the action mode overlay.

When entering action mode, the OnCreateActionMode() method is invoked. Here we create the various action items that will be presented on the actions bar.

The OnPrepareActionMode() method is invoked whenever the action mode changes or is invalidated. This method allows us to optionally modify the UI. We must return true if any changes were made and false if nothing was modified.

When the user selects an action item, the OnActionItemClicked() method will be invoked. The current action mode and the selected item are provided so that we can perform the task.

There's more...

If we are using lists and supporting Android 3.0 and above, there is an extra feature that we can make use of: multiple selections. There is currently no native support for a similar functionality on older versions of Android; however, there is no reason why we can't use this feature on newer Android versions.

Implementing this requires a few extra steps but is actually an extension of the normal contextual action mode. Instead of implementing the ActionMode.ICallback interface, implement the AbsListView.IMultiChoiceModeListener interface (which actually derives from ActionMode.ICallback). This adds one extra method:

public void OnItemCheckedStateChanged(
  ActionMode mode, int position, long id, bool isChecked) {
  // handle item selections and deselections
}

And finally, we let the list view know about the multiselect availability by passing the instance. This is done instead of registering the context menu for floating menus:

listView.ChoiceMode = ChoiceMode.MultipleModal;
listView.SetMultiChoiceModeListener(this);

See also

  • The Adding action bar action items recipe
  • The Creating a contextual menu recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset