Android - CheckBox和文本之间的间距

289

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

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

目前,文本与复选框之间的距离太近了: alt text


1
一个简单的解决方案是使用带有drawableLeftTextView,并使用drawablePadding为文本留出空间。在代码中只需切换选定和未选定状态即可。 - Muhammad Babar
我刚刚注意到一个名为android:drawablePadding的新xml属性,它被用来设置可绘制对象和文本之间的间距。虽然我还没有尝试过,但我认为这是谷歌针对这个问题的“事后补救”。 - Peri Hartman
https://dev59.com/mm855IYBdhLWcg3w_5qm#35572204 - Mohamed Ibrahim
只使用'android:padding="10dp"'对我有效。 - undefined
32个回答

355

虽然我不太想回答自己的问题,但在这种情况下我认为我需要这样做。经过检查,@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

更新 - 如下面答案中最近有人提到的,该行为在Jelly Bean(4.2)中已经改变。您的应用程序需要检查它所运行的版本,并使用相应的方法。

对于4.3及以上版本,只需设置padding_left属性即可。有关详细信息,请参见htafoya的答案。


123
回答自己的问题没有问题 - 未来可能会有其他人遇到相同的问题,而你刚好给出了一个好的、全面的答案。 - AndrewKS
5
仅设置 paddingLeft="48sp" 有什么问题吗?我这里可以正常工作,即使我更改比例和方向。但是你的代码在一系列项目上给我提供了不稳定的填充值。 - harpo
5
@harpo - 你无法保证不同的设备制造商不会为复选框使用不同的图形,这意味着你硬编码的填充可能会在不同的设备上破坏你的视觉布局。由于我正在读取当前填充并添加到它,所以这不是问题,但你必须确保只执行一次。 - DougW
2
@Blundell - 不一定。Android是开源的。设备供应商可以使用完全不同的图形和大小进行替换。由于某种原因,他们喜欢这样做。 - DougW
2
很遗憾,在自定义适配器的getView()中(如果您回收视图),您不能使用此解决方案,因为填充将无限增加。为了解决这个问题,我不得不使用类似于以下内容的东西:boolean isHackNeeded = Build.VERSION.SDK_INT < 17; float scale = context.getResources().getDisplayMetrics().density; if (isHackNeeded) {CheckBox rb = new CheckBox(context); this.PADDING = rb.getPaddingLeft() + Math.round(10.0f * scale); } else { this.PADDING = Math.round(10.0f * scale); }。然后对我膨胀的每个复选框使用PADDINGcheck.setPadding(PADDING, check.getPaddingTop() ... - Alex Semeniuk
显示剩余8条评论

157

根据@DougW的回答,我管理版本的方法更简单,我在我的复选框视图中添加:

android:paddingLeft="@dimen/padding_checkbox"

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

values

<resources>

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

</resources>

数值-v17 (4.2 果冻豆)

<resources>

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

</resources>

我有一个自定义检查,根据您的需求使用最佳的dps。


2
到目前为止,这是最好的答案。尽管根据一些上面的帖子,修复程序是在API 17中引入的,因此它实际上应该是values-v17 - icecreamman
一个完美的答案,只是针对旧的API(值/尺寸),我将padding_checkbox设置为0dip(在API 10上,边距已经很大了),而对于values-v17,像htafoya建议的那样设置为10dip。 - Yar

77

使用属性 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


1
你好,这是一个不错的方法,但要注意由于默认复选框图像而会获得额外的左边距。有解决方法吗? - Code_Life
4
设置 android:background="@android:color/transparent",左边距将消失。 - madeuz
2
以上的代码对我的单选按钮完美适用,并且在4.2操作系统版本上保持一致。谢谢! - gnichola
1
这个应该排名更高。正如@gnichola所说,它适用于各种Android版本,并且是一个非常干净的解决方案。像这样创建一个样式并在主题中分配它:<item name="android:checkboxStyle">@style/CheckBox</item>这样,您只需定义一次样式并引用一次即可。 - Rosomack
1
此外,将背景设置为null(或自定义内容),否则在Lollipop及更高版本中会出现一个巨大的圆形涟漪效果覆盖整个视图。您可以使用一个v21按钮drawable并利用<ripple>标签来放入一个更合适的涟漪效果。 - Tom

34

Android 4.2 Jelly Bean (API 17)将文本的paddingLeft从buttonDrawable(int的右边缘)开始。它还适用于RTL模式。

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

您可以通过XML解决此问题-在旧版Android上将paddingLeft设置为buttonDrawable.width + requiredSpace。在API 17及更高版本上仅设置为requiredSpace。例如,使用尺寸资源,并在values-v17资源文件夹中覆盖。

该更改是通过android.widget.CompoundButton.getCompoundPaddingLeft()引入的。


4
这是唯一正确的答案 - 它指出了问题并提供了简单的解决方案,我已在多个商业应用程序中成功使用过。 - madej
1
你如何在XML中获取buttonDrawable.width?或者你是硬编码它的? - Jared Kells
1
我通过删除 android:background="@android:color/transparent" 成功修复了旧代码中的问题。 - Sebek
被接受的答案很好并且有效,但是这个答案更简单更有效。这应该成为被接受的答案。 - Reaz Murshed

32

是的,您可以通过添加内边距来添加内边距。

android:padding=5dp


5
这确实有效...在某种程度上。首先,只需要paddingLeft而不是全部padding。但是,看起来paddingLeft的值已经设置为约40dp。如果我将其设置为> 40dp,则会移动,如果我将其设置为< 40dp,则会移动到复选框下方。我将标记此为正确,并开另一个问题,因为我对此有疑虑。 - DougW
我没有看到你的布局,所以不清楚。 - Falmarri
是的,不起作用...特别是三星设备,我遇到了问题。 - Ranjithkumar
1
通过添加填充来添加填充听起来很合理! - Sermilion
感谢 @Falmarri 的帮助,解决了我的问题。 - Ravi Vaniya

24

如果您想要一个不需要编码的简洁设计,请使用:

<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 的颜色设置为透明,并为 android:drawablePadding 分配一个值。此外,透明度允许您在任何背景颜色上使用此技术,而无需担心副作用,比如颜色不匹配。


17

在API 17及以上版本中,您可以使用:

android:paddingStart="24dp"

在API 16及以下版本中,您可以使用:

android:paddingLeft="24dp"


1
非常好的答案。我无法想象填充如何在复选框和文本之间提供空间。通常,左填充表示组件的左侧。 - Mohamed Ibrahim

16
在我的情况下,我使用以下的 CheckBox 属性在 XML 中解决了这个问题:

*

android:paddingLeft="@dimen/activity_horizontal_margin"

*

(注意:该翻译保留了原文中的 HTML 标签。)

非常好的答案。我无法想象填充如何在复选框和文本之间提供空间。通常,左填充意味着组件的左侧。 - Mohamed Ibrahim

15

简单的解决方案,将此行添加到CheckBox属性中,用您想要的间距值替换10dp

android:paddingLeft="10dp"

11

我不知道各位是否了解,但我测试了这段代码:

<CheckBox android:paddingLeft="8mm" ,发现只会将文本向右移动,并没有移动整个控件。

这个对我来说已经足够了。


1
我最近没有尝试过这个,所以它肯定有可能在特定设备或更新的Android操作系统版本上运行。但我强烈建议您在不同的设置上进行测试,因为在我提出这个问题的时候,这绝对是无法工作的。 - DougW
我发现在2.3.3和4.2之间有不同的行为(不确定在哪个版本之间发生了更改)。 - Nate
你是不是指的是 dp 而不是 mm? - Chrispix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接