如何删除可检查菜单项的末尾填充?

How to remove end padding of checkable menu item?

我有一个带有可检查菜单项的溢出菜单。我想将 CheckBox 一直对齐到最后,但我不知道如何做到这一点。

我的菜单是这样定义的:

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

您可以为 CheckBox 创建自定义样式并使用负值调整结束填充:

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

并将其应用于您应用的主题:

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

注意: 默认情况下,菜单项周围应该有一些边距;所以你不能将 checkBox 发送到远端,因为它的右边缘会被切断:

使用-8dp时:

因此,您在处理此问题时需要小心。

更新

but it affects all the CheckBoxes in my app

这需要在布局中的所有 CheckBoxes 中反转此填充;并且有选项:

  • 第一个选项:android:paddingRight="7dp" / android:paddingEnd="7dp" 添加到所有 CheckBoxes.
  • 第二个选项: 创建自定义 CheckBox class 并将此填充添加到其构造函数中;并使用这个自定义的 CheckBox 而不是默认的 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();
    }


}

并使用它:

<!-- 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"
/>

提示:如果您的目标是 API-17+,请使用 android:paddingEnd 而不是 android:paddingRight

您可以使用自定义 PopupWindow。这使您可以完全自定义它。 首先为您的 Popup 创建一个 XML 文件。在主布局中使用 wrap_content 对于将 Popup 缩小到其大小非常重要。

<?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>

然后调用这个函数显示对话框。 (我从我的一个项目中复制了这段代码,但我记得我是从 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);
}

如果你想捕捉点击事件,你只需要在LinearLayout中设置一个id,并与Java中的view一起使用(LinearLayout ll = view.findViewById(R.id.yourId);).

通过以下方式调用 void:

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