2

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 Answers 3

2
+50

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

Sign up to request clarification or add additional context in comments.

6 Comments

Also have a look at this question
This works, but it affects all the CheckBoxes in my app
@shko Absolutely right; please have a look at the updated answer; hopefully it works now.
Nice, this is probably the way to do it. Too bad these things can't be styled through Widget.AppCompat.PopupMenu.Overflow directly
I accepted the answer and gave you the bounty now. Thanks for the help
|
0

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);

2 Comments

What is p.x and p.y? The PopupWindow is laid out behind my BottomSheet, all the way to the left
Sorry, I forgot a piece of code. Check my edited answer. I also added the parameter Point p to the void.
0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.