Android Contextual Action Mode

android-contextual-action-modeContextual action mode, displays a contextual action bar at the top of the screen with action items such as “copy, share,..etc” that affect the selected item. The contextual action mode is available on Android 3.0 (API level 11) and higher

 

Objectives:

  • How to start action mode when a user long-click on a specific view?
  • How to handle user selection of an action item on the contextual action bar CAB?

Environment & Tools:

  • Android Developer Tools (ADT) (or Eclipse + ADT plugin)
  • AVD Nexus S Android 4.3 “emulator” or,
  • Min SDK 11

( 1 ) Create Android Application

  • File >> New >> Android Application
  • Enter App name: android-contextual-action-mode
  • Pakcage: com.hmkcode.android
  • Keep other defualt selections, go Next  till you reach Finish
  • res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_share"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:icon="@drawable/ic_social_share"
        android:title="Share"/>

</menu>
  • res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">App</string>

</resources>
  • res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editTextCopy"
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:layout_marginTop="19dp"
        android:ems="10"
        android:inputType="textMultiLine" 
        android:text="Long click to share!">

        <requestFocus />
    </EditText>

</RelativeLayout>

( 2 ) MainActivity implements OnLongClickListener, ActionMode.Callback {…}

  1. Get reference to editTextCopy defined in the activity_main.xml i.e. findViewById(R.id.)
  2. Set long-click listener for editTextCopy.setOnLongClickListener(this);
  3. Declare ActionMode variable “mActionMode
  4. Implement onCreateActionMode() to inflate the action mode bar with menu items “share icon” when called by startActionMode(this)
  5. Implement onActionItemClicked() what to do when user click on “share” button, here we will show a toast!
  6. onPrepareActionMode() just returns false “no change has been done on the CAB”.
  7. onDestroyActionMode() set mActionMode = null;
  • src/com/hmkcode/android/MainActivity.java
package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity implements OnLongClickListener,ActionMode.Callback {

	EditText editTextCopy;

	ActionMode mActionMode; 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 1. Get the editText
		editTextCopy = (EditText) findViewById(R.id.editTextCopy);

		// 2. add long-click listener
		editTextCopy.setOnLongClickListener(this);

	}

	@Override
	public boolean onLongClick(View view) {

		// if actionmode is null "not started"
		if (mActionMode != null) {
            return false;
        }

        // Start the CAB
        mActionMode = this.startActionMode(this);
        view.setSelected(true);
        return true;

	}

    // 4. Called when the action mode is created; startActionMode() was called
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {

    	// Inflate a menu resource providing context menu items
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;
    }

    // 5. Called when the user click share item
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_share:
            	Toast.makeText(this, "Shared!", Toast.LENGTH_SHORT).show();

                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
        }
    }

    // 6. Called each time the action mode is shown. Always called after onCreateActionMode, but
    // may be called multiple times if the mode is invalidated.
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false; // Return false if nothing is done
    }

    // 7. Called when the user exits the action mode
    @Override
    public void onDestroyActionMode(ActionMode mode) {
    	mActionMode = null;
    }

}