Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to recognize whether the Done button is clicked in ActionMode

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.

like image 320
Tanya Vybornova Avatar asked Jul 25 '12 04:07

Tanya Vybornova


3 Answers

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.

like image 60
Jake Wharton Avatar answered Nov 16 '22 23:11

Jake Wharton


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() {

    @Override
    public void onClick(View v) {
        // do whatever you want 
        // in android source code it's calling mMode.finish();
    }
});
like image 35
Alexiosdev Avatar answered Nov 16 '22 23:11

Alexiosdev


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;

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

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

@Override
public void onDestroyActionMode(ActionMode mode)
{
    mActionModeIsActive = false;

    if (!mBackWasPressedInActionMode)
        onActionModeDoneClick();

    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.

like image 11
Eurig Jones Avatar answered Nov 16 '22 22:11

Eurig Jones