Take the 2-minute tour ×

I use ActionMode to select items in a grid. The problem is that I cannot recognize whether exactly the Done button is clicked. The only I can is to know that ActionMode is finished. But pressing Back finishes the ActionMode too. The desired behavior is to accept selection on Done click, and exit ActionMode on Back press.

I tried to use ActionMode.setCustomView() but it doesn't affect the Done button. The Activity.onBackPressed() is not called when ActionMode is started.

The one solution I've found is to use ActionBarSherlock and get the Done button manually:

View closeButton = findViewById(R.id.abs__action_mode_close_button); 

But it works on Android 2.x-3.x only, because on 4.x a native action bar is used.

share|improve this question
add comment

3 Answers

up vote 15 down vote accepted

Please don't do that as it's implementation specific and extremely non-standard.

You can use the onDestroyActionMode callback for when an action mode is dismissed.

share|improve this answer
I see, but I'm implementing a picker with multiselection support and I thought that the Done button is a best way to accept selection... Any way, thanks for you answer! It seems like I have to add a menu item for accepting selected items. –  Tanya Jul 25 '12 at 6:30
But how can we distinguish from the done button and the back button? I need to implement different actions for those... –  Ricardo Amaral Oct 7 '12 at 23:01
You might be able to intercept onBackPressed. Otherwise, you can't. –  Jake Wharton Oct 7 '12 at 23:10
@JakeWharton how to distinguish the destruction of ActionMode due to screen rotation or done button . actually i have the a list of ids to add to fav database table , so if the device orientation change i should retain this array and if the user click the done button i should clear it , please help –  user4o01 Oct 9 '12 at 19:28
@JakeWharton but how about this scenario: I have a fragment with a list view in it, and that fragment is in a ViewPager. Tap and hold starts CAB, and pressing done cancels CAB. Say i'm in the middle of multiselecting things (so CAB is on). When I swipe to another fragment in the ViewPager, naturally I want to remove the CAB so to do this, I finish the actionmode on the first fragment's onPause method and when the user swipes back to that fragment, i start the CAB again. I think i should be able to differentiate dismissing CAB via swipe and via Done so that I can restart CAB onPause –  Neilers Jan 17 '13 at 13:29
show 2 more comments

Here is the solution:

ActionMode mMode = MyActivityClass.this.startActionMode(some implementation);
int doneButtonId = Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android");
View doneButton = MyActivityClass.this.findViewById(doneButtonId);
doneButton.setOnClickListener(new View.OnClickListener() {

    public void onClick(View v) {
        // do whatever you want 
        // in android source code it's calling mMode.finish();
share|improve this answer
just a side note: pay attention that you call findViewById from the activity where you started the action mode and not from an other view, or you will get a null pointer exception. –  OschtärEi Apr 16 '13 at 17:37
This does not work with ABS on pre-ICS devices like Gingerbread. –  bk138 Jun 12 '13 at 14:42
This code is only works on API LEVEL >= 11 You need to add API LEVEL condition: View doneButton; if (android.os.Build.VERSION.SDK_INT >= 11) { doneButton = Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android"); } else { doneButton = findViewById(R.id.abs__action_mode_close_button); } –  Alexiosdev Jul 5 '13 at 13:49
WARNING: this is an inflexible solution and it is essentially accessing a private API. If Google ever changes the name of action_mode_close_button, this will cease to work. –  Jon Willis Sep 13 '13 at 21:16
add comment

Here is my implementation, and it's a proper hack but it works and I can't really find an alternative to doing something specific when the ActionMode DONE is clicked. I find it really weird that you can't capture this event more elegantly.

Any suggestions to making this slightly less ugly would be greatly appreciated...

In my activity..

boolean mActionModeIsActive = false;
boolean mBackWasPressedInActionMode = false;

public boolean dispatchKeyEvent(KeyEvent event)
    mBackWasPressedInActionMode = mActionModeIsActive && event.getKeyCode() == KeyEvent.KEYCODE_BACK;
    return super.dispatchKeyEvent(event);

public boolean onCreateActionMode(ActionMode mode, Menu menu)
    mActionModeIsActive = true;
    return true;

public void onDestroyActionMode(ActionMode mode)
    mActionModeIsActive = false;

    if (!mBackWasPressedInActionMode)

    mBackWasPressedInActionMode = false;

public void onActionModeDoneClick();
    // Do something here.

If you are using Fragments with your Activity then some of this code will probably need to be in the Fragment, and the other bits in the Activity.

@JakeWharton (and other ActionBarSherlock users) if you see this on your travels. I'd be interested to know if the above is compatible with ABS as I have yet to integrate ABS with my current project.

share|improve this answer
This did work, but I am using action modes in a few places in my project. So I decided to add MenuItems to the action modes and use these as the actual "confirm" items. The main I converted the icon into a dismiss. This makes the code a lot less hacky. –  Amorgos Apr 1 '13 at 18:36
add comment

Your Answer


