21

0I'm using startActionMode(ActionMode) on my app.

By default it's add a "Done" button on the bar, I want to remove it.

Also, if there's a way to change it's text, I want to know too, cause a different description than "Done" can make the action be correspondent to the behaviour of what it does.

Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
  • Providing a picture make make it more clear what you are talking about. – JoxTraex Feb 19 '13 at 18:40
  • 2
    IMHO, what you want is invalid design. By definition, the user can dismiss the action mode, such as pressing the BACK button. An action mode should be non-destructive by default: activating an action mode, then pressing BACK (or tapping Done) should cause no changes to the user's data. – CommonsWare Feb 19 '13 at 18:40
  • Hmm.. this is also true. So there's a way to change it text so the user wouldn't be confused? Cause sometimes "Cancel" is a better description than "Done". Ty! – Marcos Vasconcelos Feb 19 '13 at 18:44
  • @MarcosVasconcelos: Perhaps via a theme. There's nothing in the API for it. – CommonsWare Feb 19 '13 at 19:01
  • Well, I tried to find something, but there's way to customize style, not the text itself. But even if there's, I need to has some Done and other Cancel. – Marcos Vasconcelos Feb 19 '13 at 20:55

5 Answers5

44

I agree with @CommonsWare that it is invalid design to hide the Done button.

However, there are customers that want to have this button removed and I can understand that the checkmark may cause confusion to users because it actually does nothing in some cases.

So, here is how to remove the button with styles:

<style name="AppTheme" parent="android:Theme.Holo">
    <item name="android:actionModeCloseButtonStyle">@style/NoCloseButton</item>
</style>

<style name="NoCloseButton" parent="@android:style/Widget.ActionButton.CloseMode">
    <item name="android:visibility">gone</item>
</style>
Matthias Robbers
  • 15,689
  • 6
  • 63
  • 73
  • Great solution for API 11+ but is there a way to do it in API 8+? I use ActionBarSherlok is there a way to hide it? ActionModeCloseButtonStyle requires API 11+ – Cilenco May 25 '13 at 22:03
  • 3
    @Cilenco: `actionModeCloseButtonStyle` (without `android:`) should work for ABS. – Matthias Robbers May 25 '13 at 22:38
  • You are right thank you I added a answer which works with ABS vor Android API8+ – Cilenco May 25 '13 at 23:22
  • 2
    It works but, If i inflate custom layout it is not occupying entire width. That is the only issue with this. – sandeepmaaram Feb 09 '15 at 13:46
  • 1
    @MatthiasRobbers I have applies the above style for CAB, with visibility as gone for NoCloseButton, it still occupies space and is not allowing to add additional icons – krisDrOid Feb 10 '15 at 07:55
2

If you are using ActionBarSherlock you can hide the "Done" button with this style:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="NoCloseButton" parent="@style/Widget.Sherlock.ActionButton.CloseMode">
        <item name="android:visibility">gone</item>
    </style>

    <style name="AppBaseTheme" parent="Theme.Sherlock.Light.DarkActionBar">
        <item name="actionModeCloseButtonStyle">@style/NoCloseButton</item>
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">

    </style>
</resources>

Please make sure to put this style in each style directory (values, value-v11, values-v14). After that you can create a custom menu with this code:

LayoutInflater inflater = LayoutInflater.from(getSherlockActivity());
View actionView = inflater.inflate(R.layout.actionmode, null);

ActionMode am = getSherlockActivity().startActionMode(mActionModeCallback);
am.setCustomView(actionView);
Cilenco
  • 6,951
  • 17
  • 72
  • 152
1

Even I was stuck with same and I found this way to solve it.

int doneButtonId = Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android");
LinearLayout layout = (LinearLayout) findViewById(doneButtonId);
TextView doneview = (TextView) layout.getChildAt(1);
doneview.setText("");

Hope this helps!!

paibhavesh
  • 167
  • 5
  • 11
    This is an unreliable solution, as it assumes implementation details that are subject to change. – CommonsWare Aug 07 '13 at 19:01
  • 1
    not working i tried this i am getting null pointer exception, when should i call this method, i am using fragment – Iftikar Urrhman Khan Feb 28 '14 at 09:14
  • 1
    Null pointer exception is because ActionMode has not been complete initialized. Try to use view.postDelayed (Runnable action, long delayMillis) to delay a period in onCreateActionMode() method!!! – codezjx Mar 13 '15 at 11:09
1

Thanks for Matthias Robbers, it works. But i perfer to use "invisible":

<style name="NoCloseButtonActionModeStyle">
   <item name="android:visibility">invisible</item>
</style>

So the custom view position in ActionMode will not indent to parent left.

Community
  • 1
  • 1
codezjx
  • 9,012
  • 5
  • 47
  • 57
0

any one find out screen width solution? – Mayur R. Amipara Jun 5 '15 at 10:27

override your custom view's onMeasure, set it's width to screen width. and in onLayout, relayout your child views.

it works for me.

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.RelativeLayout;

import com.android.gallery3d.R;

public class SelectActionModeCustomView extends RelativeLayout {

    private View mLeftButton;
    private View mRightButton;

    private int mScreenWidth;

    private static final String TAG = "SelectActionView";

    public SelectActionModeCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);

        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        mScreenWidth = metrics.widthPixels;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mLeftButton = findViewById(R.id.cancel);
        mRightButton = findViewById(R.id.select_action);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        this.setMeasuredDimension(mScreenWidth, this.getMeasuredHeight());
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        int childLeft = 0;
        int childTop = 0;

        childLeft = 0;
        childTop = ((b - t) - mLeftButton.getMeasuredHeight()) / 2;
        mLeftButton.layout(childLeft, childTop, 
                childLeft + mLeftButton.getMeasuredWidth(), 
                childTop + mLeftButton.getMeasuredHeight());

        childLeft = (r - l) - mRightButton.getMeasuredWidth();
        childTop = ((b - t) - mRightButton.getMeasuredHeight()) / 2;
        mRightButton.layout(childLeft, childTop, 
                childLeft + mRightButton.getMeasuredWidth(), 
                childTop + mRightButton.getMeasuredHeight());
    }


}
VinceShen
  • 1
  • 1