En la aplicación Open Event Android Organizer, estábamos utilizando la barra de acciones de Android como barra de herramientas para permitir la eliminación y edición de los elementos de la lista, pero esta implementación era defectuosa y no cumplía con los estándares de la industria. Decidimos implementar esto utilizando la Barra de Acción Contextual como una barra de herramientas de selección.


Especificaciones

Estamos utilizando la arquitectura MVP, por lo que habrá una clase Fragment para interactuar con la interfaz de usuario y una clase Presenter para manejar toda la lógica empresarial e interactuar con la capa de red.

La clase SessionsFragment es la clase Fragment para mostrar la lista de sesiones al usuario. Podemos mantener presionado cualquier elemento para seleccionarlo, ingresando al modo de barra de acción contextual. Usando esto, podremos seleccionar varios elementos de la lista con un clic y eliminar/editar desde la barra de herramientas.

Para entrar en el modo de Barra de Acción Contextual, use

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

  

Para salir del modo de Barra de Acción Contextual, use

    if (actionMode != null)

      actionMode.finish();

  

onCreateActionMode: Este método se ejecuta cuando se crea la barra de acción contextual. Inflaremos el menú de la barra de herramientas usando MenuInflator y estableceremos el nuevo color de la barra de estado.

onPrepareActionMode: Este método se ejecuta después de onCreateActionMode y también cada vez que la Barra de Acción Contextual se invalida, por lo que estableceremos la visibilidad del botón de eliminación en la barra de herramientas aquí y devolveremos true para indicar que hemos realizado algunos cambios.

onActionItemClicked: Este método se ejecuta cada vez que se hace clic en un elemento del menú en la barra de herramientas. Llamaremos a la función showDeleteDialog.

onDestroyActionMode: Este método se ejecuta cada vez que el usuario abandona el modo de barra de acción contextual presionando el botón Atrás en la barra de herramientas o el botón Atrás en el teclado, etc. Aquí deseleccionaremos todos los elementos de la lista seleccionados y restableceremos el color de la barra de estado.

Implementaremos la interfaz Action.Callback en nuestra clase de fragmento. Contiene tres declaraciones de métodos:

    // Métodos de la interfaz Action.Callback

    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) {
            // Volver al color "antiguo" de la barra de estado
            getActivity().getWindow().setStatusBarColor(statusBarColor);
        }
    }
};
  

Método showDeleteDialog

    // Código del método showDeleteDialog

    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();
}
  

Recursos