How to remove end padding of checkable menu item?

746 views Asked by At

I have an overflow menu with a checkable menu item. I would like to align the CheckBox all the way to the end, but I don't know how this can be done.

My menu is defined like so:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:icon="@drawable/ic_baseline_more_vert_24"
        android:title=""
        app:showAsAction="always">
        <menu>
            <item
                android:id="@+id/desktop_site"
                android:checkable="true"
                android:checked="false"
                android:icon="@drawable/ic_baseline_desktop_windows_24"
                android:title="Desktop site"
                app:showAsAction="never" />
        </menu>
    </item>
</menu>

Overflow menu

3

There are 3 answers

6
Zain On BEST ANSWER

You can create a custom style to the CheckBox and adjust the end padding with a negative value:

<style name="checkbox_style" parent="android:style/Widget.Holo.Light.CompoundButton.CheckBox">
    <item name="android:paddingRight">-7dp</item>
</style>

And apply it to your app's theme:

<item name="checkboxStyle">@style/checkbox_style</item>

enter image description here

Note: By default there should be some margin surrounds a menu item; so you can't send the checkBox to the far end, as its right edge will cut:

When using -8dp:

enter image description here

So, you need to be careful in handling this.

UPDATE

but it affects all the CheckBoxes in my app

This requires to reverse this padding in all of CheckBoxes in your layouts; and there are options for this:

  • First option: add android:paddingRight="7dp" / android:paddingEnd="7dp" to all the CheckBoxes.
  • Second option: Create a custom CheckBox class and add this padding to its constructors; and use this customized CheckBox instead of the default CheckBox:
public class MyCheckBox extends AppCompatCheckBox {

    public MyCheckBox(Context context) {
        super(context);
        init();
    }

    public MyCheckBox(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        int px = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                7f, // dp value
                getResources().getDisplayMetrics()
        );
        setPadding(0, 0, px, 0);
    }

    public MyCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


}

And to use it:

<!-- Add the full path of the customized CheckBox -->
<com.example.android......MyCheckBox   
    android:id="@+id/checkbox2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
/>

Hint: If you target API-17+, then use android:paddingEnd instead android:paddingRight

2
Jakob On

You can use a custom PopupWindow. This allows you to completely customize it. First create a XML file of your Popup. Using wrap_content at the main layout is very important to shrink the Popup to its size.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#000000"
        android:padding="5dp"
        android:gravity="center_vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_baseline_desktop_mac_24"
            app:tint="#FFFFFF"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Desktop site"
            android:textColor="#FFFFFF"
            android:layout_marginLeft="10dp"/>

        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:buttonTint="#FFFFFF"
            android:minWidth="0dp"
            android:minHeight="0dp"
            android:layout_marginLeft="30dp"/>

    </LinearLayout>

</LinearLayout>

enter image description here

Then show the dialog by calling this function. (I copied this code from one of my projects, but I can remember I got it from SO).

private void showPopup(Context context, Point p) {
    LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View layout = layoutInflater.inflate(R.layout.your_popup_xml, null);
    
    PopupWindow changeStatusPopUp = new PopupWindow(context);
    changeStatusPopUp.setContentView(layout);
    changeStatusPopUp.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
    changeStatusPopUp.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
    changeStatusPopUp.setAnimationStyle(android.R.style.Animation_Dialog);

    int OFFSET_X = -300; //Adjust position of the Popup
    int OFFSET_Y = 50;   //Adjust position of the Popup
        
    changeStatusPopUp.setOutsideTouchable(true);
    changeStatusPopUp.setFocusable(true);
    changeStatusPopUp.setBackgroundDrawable(new BitmapDrawable());
    changeStatusPopUp.showAtLocation(layout, Gravity.NO_GRAVITY, p.x + OFFSET_X, p.y + OFFSET_Y);
}

If you want to catch Click Events, you just need to set an id to the LinearLayout and use it with the view in Java (LinearLayout ll = view.findViewById(R.id.yourId);).

Call the void by:

int[] location = new int[2];
view.getLocationOnScreen(location);
Point point = new Point();
point.x = location[0];
point.y = location[1];
showStatusPopup(context, point);
0
repkap11 On

When using MaterialComponents some of the padding is from the checkbox itself. This can be removed by setting android:minWidth to 0. The remaining padding is symmetrical and looks good.

Like the accepted solution, create a style:

<style name="checkbox_style" parent="@style/Widget.MaterialComponents.CompoundButton.CheckBox">
    <item name="minWidth">0dp</item>
</style>

And apply it to your app's theme:

<item name="checkboxStyle">@style/checkbox_style</item>