Using Contextual Action Bar as Selection Toolbar

In Open Event Android Organizer App we were using Android Action Bar as Toolbar to allow deleting and editing of the list items but this implementation was buggy and not upto the industry standards. So we decided to implement this using Contextual Action Bar as a selection toolbar.

Specifications

We are using MVP Architecture so there will be Fragment class to interact with the UI and Presenter class to handle all the business logic and interact with network layer.

The SessionsFragment is the Fragment class for displaying List of Sessions to the user. We can long press any item to select it, entering into contextual action bar mode. Using this we will be able to select multiple items from list by a click and delete/edit them from toolbar.

To enter in Contextual Action Bar Mode use

ActionMode actionMode = getActivity().startActionMode(actionCallback);

To exit Contextual Action Bar Mode use

if (actionMode != null)
actionMode.finish();

We will implement Action.Callback interface in out fragment class. It’s contains three method declarations –

  1. onCreateActionMode – This method is executed when the contextual action bar is  created. We will inflate the toolbar menu using MenuInflator and set new status bar color.
  2. onPrepareActionMode – This method is executed after onCreateActionMode and also whenever the Contextual Action Bar is invalidated so we will set the visibility of delete button in toolbar here and return true to ignify that we have made some changes.
  3. onActionItemClicked – This method is executed whenever a menu item in toolbar is clicked. We will call the function showDeleteDialog.
  4. onDestroyActionMode – This method is executed whenever user leaves the contextual action bar mode by pressing back button on toolbar or back button in keyboard etc. Here we will make unselect all the selected list items and the status bar color.
public ActionMode.Callback actionCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_sessions, menu);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
statusBarColor = getActivity().getWindow().getStatusBarColor();
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.color_top_surface));
}
return true;
}@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
MenuItem menuItemDelete = menu.findItem(R.id.del);
MenuItem menuItemEdit = menu.findItem(R.id.edit);
menuItemEdit.setVisible(editMode);
menuItemDelete.setVisible(deletingMode);
return true;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.del:
showDeleteDialog();
break;
case R.id.edit:
getPresenter().updateSession();
break;
default:
return false;
}
return false;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
getPresenter().resetToolbarToDefaultState();
getPresenter().unselectSessionList();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//return to “old” color of status bar
getActivity().getWindow().setStatusBarColor(statusBarColor);
}
}
};

The showDeleteDialog method shows a AlertDialog to the user before deleting the selected items in the list. User can click on Ok to delete the items or on Cancel to close the dialog.

public void showDeleteDialog() {
if (deleteDialog == null)
deleteDialog = new AlertDialog.Builder(context)
.setTitle(R.string.delete)
.setMessage(String.format(getString(R.string.delete_confirmation_message),
getString(R.string.session)))
.setPositiveButton(R.string.ok, (dialog, which) -> {
getPresenter().deleteSelectedSessions();
})
.setNegativeButton(R.string.cancel, (dialog, which) -> {
dialog.dismiss();
})
.create();deleteDialog.show();
}

When user presses Ok then we call the method deleteSelectedSessions in presenter to delete the sessions.

Resources

  1. Offical doumentation for Contextual Action Bar by Google https://developer.android.com/guide/topics/ui/menus#CAB
  2. Official Documentation for Alert Dialog by Google https://developer.android.com/guide/topics/ui/dialogs
  3. Codebase for Open Event OrganIzer App on Github https://github.com/fossasia/open-event-orga-app/
Continue Reading

Implementing Contextual Action Bar in the Open Event Organizers App

The following blog post is regarding the using of Contextual Action Bar in the Open Event Orga App. In the Open Event Orga App, whenever an item was long pressed, then we had implemented a non standard way of showing the edit and delete button at the top. This would eventually degrade the UX of the app. So as to handle this, CAB was implemented.

When the user long presses on any item, we sometimes see a list of items such as Share, Delete or Edit on the toolbar. This is a standard functionality known as the Contextual Action Bar which is present in many apps. (image for reference given below)

Apart from the standard Action Bar, Android also provides us with the implementation of the Contextual Action Menu. A context menu is a floating menu that appears when the user performs a long-click on an element. It provides actions that affect the selected content or context frame.( image given below for reference)

(Contextual Action Bar)

(Contextual Action Menu)

To implement the standard CAB in the Orga App, the following steps given below have been followed.

In the FaqlistFragment class, an interface ActionMode.Callback is implemented. In its callback methods, you can specify the actions for the contextual action bar, respond to click events on action items, and handle other lifecycle events for the action mode.

Each of the callback methods have been discussed below:

  • onCreateActionMode( ) ->  This method is called first when the ActionMode is started. Here with the help of MenuInflater, the menu which has been made in the menus.xml file is inflated. Also when the app goes into Actions Mode , the status bar is black in color. Hence to handle that the color of the status bar is being changed programmatically.

 

  • onPrepareActionMode( ) -> This should generally return true.

  • onActionItemClicked( ) -> The action mode consists of many items which have separate action. The separate actions for the items are defined here. For eg.In the code snippet given below, when the icon with the id “del is selected then the showDeleteDialog( ) must be called.

 

  • onDestroyActionMode( ) -> When the user exits the Actions Mode, the mode should be assigned a null value and the app should be set to default state.
public ActionMode.Callback actionCallback = new ActionMode.Callback() {
  @Override
  public boolean onCreateActionMode(ActionMode mode, Menu menu) {
      MenuInflater inflater = mode.getMenuInflater();
      inflater.inflate(R.menu.menu_faqs, menu);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          //hold current color of status bar
          statusBarColor = getActivity().getWindow().getStatusBarColor();
          //set the default color
          getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.color_top_surface));
      }
      return true;
  }

  @Override
  public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
       return true;
  }

  @Override
  public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
      switch (item.getItemId()) {
          case R.id.del:
              showDeleteDialog();
              break;
          default:
              return false;
      }
      return false;
  }

  @Override
  public void onDestroyActionMode(ActionMode mode) {
      actionMode = null;
      getPresenter().resetToDefaultState();
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          //return to “old” color of status bar
          getActivity().getWindow().setStatusBarColor(statusBarColor);
      }
  }
};
  1. In the styles.xml, the XML Tag given below needs to be added so that the Action Mode replaces the current Action Bar otherwise, a new Action Bar is created above the Action Bar which is already present.

 <item name=“windowActionModeOverlay”>true</item>

  1. In the Orga App, as the MVP pattern is followed we need to add the following to methods to the interface so that the View and Presenter can communicate via these methods.
public interface FaqListView extends Progressive, Erroneous, Refreshable, Emptiable<Faq> {

  void exitContextualMenuMode();

  void enterContextualMenuMode();
}

 

  1. In the enterContextualMenuMode( ) implementation in the FaqListFragment the startActionMode()  is called to enable the contextual action mode.
@Override
public void enterContextualMenuMode() {
  actionMode = getActivity().startActionMode(actionCallback);
}

References:

  • Official Android documentation for Menu’s

https://developer.android.com/guide/topics/ui/menus#CAB

  • Sample CAB implementation

http://www.technotalkative.com/contextual-action-bar-cab-android/

  • Action mode over Toolbar

http://www.androhub.com/android-contextual-action-mode-over-toolbar/            

Continue Reading
Close Menu