Android -复选框和文本之间的空格

是否有一种简单的方法可以在复选框控件中的复选框和相关文本之间添加填充?

我不能只添加前导空格,因为我的标签是多行。

As-is,文本太接近复选框: alt text

159249 次浏览

是的,您可以通过添加填充来添加填充。

android:padding=5dp

<CheckBox
android:paddingRight="12dip" />

我讨厌回答我自己的问题,但在这种情况下,我认为我需要回答。在检查之后,@Falmarri的答案是正确的。问题是Android的CheckBox控件已经使用Android:paddingLeft属性来获取文本所在的位置。

红线显示了整个CheckBox的paddingLeft偏移值

alt text

如果我重写XML布局中的填充,它就会把布局弄乱。下面是设置paddingLeft="0"的作用:

alt text

事实证明,在XML中无法解决这个问题。你必须用代码来做。下面是我的片段,硬编码填充增加10dp。

final float scale = this.getResources().getDisplayMetrics().density;
checkBox.setPadding(checkBox.getPaddingLeft() + (int)(10.0f * scale + 0.5f),
checkBox.getPaddingTop(),
checkBox.getPaddingRight(),
checkBox.getPaddingBottom());

这将得到以下结果,其中绿线是填充的增加。这比硬编码一个值更安全,因为不同的设备可以为复选框使用不同的绘图。

alt text

更新-正如人们最近在下面的回答中提到的,这种行为在果冻豆(4.2)中明显发生了变化。你的应用需要检查它运行在哪个版本上,并使用适当的方法。

对于4.3+,它只是设置padding_left。详情请看htafoya的回答。

我不知道,但我试过了

<CheckBox android:paddingLeft="8mm"并且只将文本向右移动,而不是整个控件。

它很适合我。

如果你正在创建自定义按钮,例如,参见更改复选框教程的外观

然后简单地增加btn_check_label_background.9.png的宽度,在图像中心增加一到两列透明像素;让9个补丁标记保持原样。

为什么不扩展Android复选框以获得更好的填充呢?这样一来,每次使用复选框时都不必在代码中修复它,而只需使用固定的复选框即可。

第一个扩展复选框:

package com.whatever;


import android.content.Context;
import android.util.AttributeSet;
import android.widget.CheckBox;


/**
* This extends the Android CheckBox to add some more padding so the text is not on top of the
* CheckBox.
*/
public class CheckBoxWithPaddingFix extends CheckBox {


public CheckBoxWithPaddingFix(Context context) {
super(context);
}


public CheckBoxWithPaddingFix(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


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


@Override
public int getCompoundPaddingLeft() {
final float scale = this.getResources().getDisplayMetrics().density;
return (super.getCompoundPaddingLeft() + (int) (10.0f * scale + 0.5f));
}
}

其次,在xml中创建一个扩展的复选框,而不是创建一个普通的复选框

<com.whatever.CheckBoxWithPaddingFix
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello there" />

使用属性android:drawableLeft代替android:button。为了设置可绘制和文本之间的填充,请使用android:drawablePadding。要定位可绘制的位置使用android:paddingLeft

<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:drawableLeft="@drawable/check_selector"
android:drawablePadding="-50dp"
android:paddingLeft="40dp"
/>

result

这种行为在果冻豆中似乎发生了改变。paddingLeft技巧增加了额外的填充,使文本看起来太靠右了。有人注意到吗?

如果你有自定义图像选择框或单选按钮,你必须设置相同的按钮和背景属性,如下所示:

            <CheckBox
android:id="@+id/filter_checkbox_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@drawable/selector_checkbox_filter"
android:background="@drawable/selector_checkbox_filter" />

您可以用背景属性控制复选框或单选按钮填充的大小。

android4.2果冻豆(API 17)把文本填充左从buttonDrawable(整数右边缘)。它也适用于RTL模式。

在4.2之前,paddingLeft忽略了buttonDrawable -它是从CompoundButton视图的左边缘取的。

你可以通过XML来解决这个问题——设置paddingLeft到buttonDrawable。width + requiredSpace在旧的机器人。只在API 17上设置为requiredSpace。例如,使用维度资源并覆盖values-v17资源文件夹。

这个变化是通过android.widget.CompoundButton.getCompoundPaddingLeft()引入的;

<CheckBox android:drawablePadding="16dip" - drawables和文本之间的填充。

如果你想要一个没有代码的干净的设计,使用:

<CheckBox
android:id="@+id/checkBox1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:drawableLeft="@android:color/transparent"
android:drawablePadding="10dp"
android:text="CheckBox"/>

诀窍是将android:drawableLeft的colour设置为transparent,并为android:drawablePadding赋值。此外,透明度允许你在任何背景颜色上使用这种技术,而不会产生类似颜色不匹配的副作用。

我刚才的结论是:

覆盖CheckBox并添加此方法,如果你有一个自定义绘制对象:

@Override
public int getCompoundPaddingLeft() {


// Workarround for version codes < Jelly bean 4.2
// The system does not apply the same padding. Explantion:
// http://stackoverflow.com/questions/4037795/android-spacing-between-checkbox-and-text/4038195#4038195


int compoundPaddingLeft = super.getCompoundPaddingLeft();


if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
Drawable drawable = getResources().getDrawable( YOUR CUSTOM DRAWABLE );
return compoundPaddingLeft + (drawable != null ? drawable.getIntrinsicWidth() : 0);
} else {
return compoundPaddingLeft;
}


}

或者如果你使用系统绘图:

@Override
public int getCompoundPaddingLeft() {


// Workarround for version codes < Jelly bean 4.2
// The system does not apply the same padding. Explantion:
// http://stackoverflow.com/questions/4037795/android-spacing-between-checkbox-and-text/4038195#4038195


int compoundPaddingLeft = super.getCompoundPaddingLeft();


if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
final float scale = this.getResources().getDisplayMetrics().density;
return compoundPaddingLeft + (drawable != null ? (int)(10.0f * scale + 0.5f) : 0);
} else {
return compoundPaddingLeft;
}


}

谢谢你的回答:)

鉴于@DougW的响应,我所做的管理版本更简单,我添加到我的复选框视图:

android:paddingLeft="@dimen/padding_checkbox"

在两个值文件夹中找到dimen:

<resources>


<dimen name="padding_checkbox">0dp</dimen>


</resources>

values-v17 (4.2 JellyBean)

<resources>


<dimen name="padding_checkbox">10dp</dimen>


</resources>

我有定制check,用dps给你最好的选择。

您需要获取正在使用的图像的大小,以便将填充添加到此大小。在Android内部,它们获取你在src上指定的drawable,然后使用它的大小。因为它是一个私有变量,没有getter,你不能访问它。同样,你也不能得到com.android.internal.R.styleable.CompoundButton并从那里得到drawable。

所以你需要创建你自己的可样式(即custom_src),或者你可以直接在你的RadioButton的实现中添加它:

public class CustomRadioButton extends RadioButton {


private Drawable mButtonDrawable = null;


public CustomRadioButton(Context context) {
this(context, null);
}


public CustomRadioButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}


public CustomRadioButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mButtonDrawable = context.getResources().getDrawable(R.drawable.rbtn_green);
setButtonDrawable(mButtonDrawable);
}


@Override
public int getCompoundPaddingLeft() {
if (Util.getAPILevel() <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (drawable != null) {
paddingLeft += drawable.getIntrinsicWidth();
}
}
return paddingLeft;
}
}

而不是调整复选框的文本,我已经做了以下事情,它适用于我所有的设备。 1)在XML中,依次添加复选框和textview;保持一定距离。 2)设置复选框文本大小为0sp。 3)在复选框旁边的textview中添加相对文本

我所做的是在(相对)Layout中有一个TextView和一个CheckBoxTextView显示我想让用户看到的文本,而CheckBox没有任何文本。这样,我可以设置CheckBox的位置/填充。

因为你可能会为你的android:button属性使用一个可绘制的选择器,你需要添加android:constantSize="true"和/或指定一个默认的可绘制的对象,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
<item android:drawable="@drawable/check_on" android:state_checked="true"/>
<item android:drawable="@drawable/check_off"/>
</selector>

之后,你需要在你的复选框xml中指定android:paddingLeft属性。

缺点:

在布局编辑器中,你会将文本放在带有api 16及以下的复选框下面,在这种情况下,你可以通过创建自定义复选框类来修复它,如建议,但适用于api级别16。

理由是:

这是一个bug,因为StateListDrawable#getIntrinsicWidth()调用在CompoundButton中内部使用,但如果没有当前状态且没有使用常量大小,则可能返回< 0值。

你所要做的就是在你的android xml布局的checkBox中添加android:singleLine="true"来克服这个问题:

<CheckBox
android:id="@+id/your_check_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:background="@android:color/transparent"
android:text="@string/your_string"/>

并且不会以编程方式添加任何特殊内容。

当我使用自己的绘图选择器时,复选框图像重叠,我用下面的代码解决了这个问题:

CheckBox cb = new CheckBox(mActivity);
cb.setText("Hi");
cb.setButtonDrawable(R.drawable.check_box_selector);
cb.setChecked(true);
cb.setPadding(cb.getPaddingLeft(), padding, padding, padding);

感谢Alex Semeniuk

简单的解决方案,在复选框属性中添加这一行,用你想要的空格值替换10 dp

android:paddingLeft="10dp"

在XML文件中只需要有一个参数

android:paddingLeft="20dp"

API 17及以上,你可以使用:

android: paddingStart = " 24 dp "

API 16及以下,你可以使用:

android: paddingLeft = " 24 dp "

在我的情况下,我解决了这个问题使用以下复选框属性在XML:

android: paddingLeft = " @dimen / activity_horizontal_margin”

我通过改变图像来解决这个问题。 刚刚在png文件中添加了额外的透明背景。 这个解决方案在所有api上都非常出色

也许已经太晚了,但是我已经创建了实用工具方法来管理这个问题。

只需将这些方法添加到您的utils:

public static void setCheckBoxOffset(@NonNull  CheckBox checkBox, @DimenRes int offsetRes) {
float offset = checkBox.getResources().getDimension(offsetRes);
setCheckBoxOffsetPx(checkBox, offset);
}


public static void setCheckBoxOffsetPx(@NonNull CheckBox checkBox, float offsetInPx) {
int leftPadding;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
leftPadding = checkBox.getPaddingLeft() + (int) (offsetInPx + 0.5f);
} else {
leftPadding = (int) (offsetInPx + 0.5f);
}
checkBox.setPadding(leftPadding,
checkBox.getPaddingTop(),
checkBox.getPaddingRight(),
checkBox.getPaddingBottom());
}

像这样使用:

    ViewUtils.setCheckBoxOffset(mAgreeTerms, R.dimen.space_medium);

或者像这样:

    // Be careful with this usage, because it sets padding in pixels, not in dp!
ViewUtils.setCheckBoxOffsetPx(mAgreeTerms, 100f);

我有一个Galaxy S3 mini (android 4.1.2)同样的问题,我只是让我的自定义复选框扩展AppCompatCheckBox而不是checkbox。现在它工作得很完美。

对于复选符号和文本之间的空格,使用:

android:paddingLeft="10dp"

但它会超过10dp,因为选中标记周围包含填充(大约5dp)。如果你想移除填充,请参见如何删除周围的Android复选框填充:

android:paddingLeft="-5dp"
android:layout_marginStart="-5dp"
android:layout_marginLeft="-5dp"
// or android:translationX="-5dp" instead of layout_marginLeft

设置minHeight和minWidth为0dp是我在Android 9 API 28上最干净和最直接的解决方案:

<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:minWidth="0dp" />

@CoolMind有很好的方法,但它不能通过android:paddingLeft在复选框的开头添加空格,而是使用这种方法

<androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/cbReason5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:button="@null"
android:drawableStart="@drawable/custom_bg_checkbox"
android:drawablePadding="8dp"
android:paddingStart="16dp"
android:paddingTop="12dp"
android:paddingEnd="16dp"
android:paddingBottom="12dp"
android:text="Whatever"
android:textColor="@color/textNormal"
app:buttonCompat="@null" />

android:drawablePadding应该帮助你

我想这个能帮到你

<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="-30dp"
android:paddingLeft="30dp"
android:drawableLeft="@drawable/check"
/>

如果有人需要填充周围的可绘制尝试这

        <com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:drawableStart="@drawable/button_selector"
android:padding="@dimen/items_padding" />