Android - Spacing between CheckBox and text
AndroidCheckboxPaddingAndroid Problem Overview
Is there an easy way to add padding between the checkbox in a CheckBox control, and the associated text?
I cannot just add leading spaces, because my label is multi-line.
As-is, the text is way too close to the checkbox:
Android Solutions
Solution 1 - Android
I hate to answer my own question, but in this case I think I need to. After checking it out, @Falmarri was on the right track with his answer. The problem is that Android's CheckBox control already uses the android:paddingLeft property to get the text where it is.
The red line shows the paddingLeft offset value of the entire CheckBox
If I just override that padding in my XML layout, it messes up the layout. Here's what setting paddingLeft="0" does:
Turns out you can't fix this in XML. You have do it in code. Here's my snippet with a hardcoded padding increase of 10dp.
final float scale = this.getResources().getDisplayMetrics().density;
checkBox.setPadding(checkBox.getPaddingLeft() + (int)(10.0f * scale + 0.5f),
checkBox.getPaddingTop(),
checkBox.getPaddingRight(),
checkBox.getPaddingBottom());
This gives you the following, where the green line is the increase in padding. This is safer than hardcoding a value, since different devices could use different drawables for the checkbox.
UPDATE - As people have recently mentioned in answers below, this behavior has apparently changed in Jelly Bean (4.2). Your app will need to check which version its running on, and use the appropriate method.
For 4.3+ it is simply setting padding_left. See htafoya's answer for details.
Solution 2 - Android
Given @DougW response, what I do to manage version is simpler, I add to my checkbox view:
android:paddingLeft="@dimen/padding_checkbox"
where the dimen is found in two values folders:
values
<resources>
<dimen name="padding_checkbox">0dp</dimen>
</resources>
values-v17 (4.2 JellyBean)
<resources>
<dimen name="padding_checkbox">10dp</dimen>
</resources>
I have a custom check, use the dps to your best choice.
Solution 3 - Android
Use attribute android:drawableLeft
instead of android:button
. In order to set padding between drawable and text use android:drawablePadding
. To position drawable use 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"
/>
Solution 4 - Android
Android 4.2 Jelly Bean (API 17) puts the text paddingLeft from the buttonDrawable (ints right edge). It also works for RTL mode.
Before 4.2 paddingLeft was ignoring the buttonDrawable - it was taken from the left edge of the CompoundButton view.
You can solve it via XML - set paddingLeft to buttonDrawable.width + requiredSpace on older androids. Set it to requiredSpace only on API 17 up. For example use dimension resources and override in values-v17 resource folder.
The change was introduced via android.widget.CompoundButton.getCompoundPaddingLeft();
Solution 5 - Android
Yes, you can add padding by adding padding.
android:padding=5dp
Solution 6 - Android
If you want a clean design without codes, use:
<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"/>
The trick is to set colour to transparent for android:drawableLeft
and assign a value for android:drawablePadding
. Also, transparency allows you to use this technique on any background colour without the side effect - like colour mismatch.
Solution 7 - Android
API 17 and above, you can use:
> android:paddingStart="24dp"
API 16 and below, you can use:
> android:paddingLeft="24dp"
Solution 8 - Android
In my case I solved this problem using this following CheckBox attribute in the XML:
> android:paddingLeft="@dimen/activity_horizontal_margin"
Solution 9 - Android
Simple solution, add this line in the CheckBox properties, replace 10dp with your desired spacing value
android:paddingLeft="10dp"
Solution 10 - Android
I don't know guys, but I tested
<CheckBox android:paddingLeft="8mm"
and only moves the text to the right, not entire control.
It suits me fine.
Solution 11 - Android
Why not just extend the Android CheckBox to have better padding instead. That way instead of having to fix it in code every time you use the CheckBox you can just use the fixed CheckBox instead.
First Extend CheckBox:
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));
}
}
Second in your xml instead of creating a normal CheckBox create your extended one
<com.whatever.CheckBoxWithPaddingFix
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello there" />
Solution 12 - Android
For space between the check mark and the text use:
android:paddingLeft="10dp"
But it becomes more than 10dp, because the check mark contains padding (about 5dp) around. If you want to remove padding, see https://stackoverflow.com/questions/14496265/how-to-remove-padding-around-android-checkbox:
android:paddingLeft="-5dp"
android:layout_marginStart="-5dp"
android:layout_marginLeft="-5dp"
// or android:translationX="-5dp" instead of layout_marginLeft
Solution 13 - Android
Setting minHeight and minWidth to 0dp
was the cleanest and directest solution for me on 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" />
Solution 14 - Android
I just concluded on this:
Override CheckBox and add this method if you have a custom drawable:
@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;
}
}
or this if you use the system drawable:
@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;
}
}
Thanks for the answer :)
Solution 15 - Android
only you need to have one parameter in xml file
android:paddingLeft="20dp"
Solution 16 - Android
This behavior appears to have changed in Jelly Bean. The paddingLeft trick adds additional padding, making the text look too far right. Any one else notice that?
Solution 17 - Android
<CheckBox
android:paddingRight="12dip" />
Solution 18 - Android
If you have custom image selector for checkbox or radiobutton you must set same button and background property such as this:
<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" />
You can control size of checkbox or radio button padding with background property.
Solution 19 - Android
If you are creating custom buttons, e.g. see change look of checkbox tutorial
Then simply increase the width of btn_check_label_background.9.png by adding one or two more columns of transparent pixels in the center of the image; leave the 9-patch markers as they are.
Solution 20 - Android
What I did, is having a TextView
and a CheckBox
inside a (Relative)Layout
. The TextView
displays the text that I want the user to see, and the CheckBox
doesn't have any text. That way, I can set the position / padding of the CheckBox
wherever I want.
Solution 21 - Android
I had the same problem with a Galaxy S3 mini (android 4.1.2) and I simply made my custom checkbox extend AppCompatCheckBox instead of CheckBox. Now it works perfectly.
Solution 22 - Android
You need to get the size of the image that you are using in order to add your padding to this size. On the Android internals, they get the drawable you specify on src and use its size afterwards. Since it's a private variable and there are no getters you cannot access to it. Also you cannot get the com.android.internal.R.styleable.CompoundButton and get the drawable from there.
So you need to create your own styleable (i.e. custom_src) or you can add it directly in your implementation of the 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;
}
}
Solution 23 - Android
As you probably use a drawable selector for your android:button
property you need to add android:constantSize="true"
and/or specify a default drawable like this:
<?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>
After that you need to specify android:paddingLeft
attribute in your checkbox xml.
Cons:
In the layout editor you will the text going under the checkbox with api 16 and below, in that case you can fix it by creating you custom checkbox class like suggested but for api level 16.
Rationale:
it is a bug as StateListDrawable#getIntrinsicWidth()
call is used internally in CompoundButton
but it may return < 0
value if there is no current state and no constant size is used.
Solution 24 - Android
All you have to do to overcome this problem is to add android:singleLine="true"
to the checkBox
in your android xml layout:
<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"/>
and nothing special will be added programmatically.
Solution 25 - Android
Checkbox image was overlapping when I used my own drawables from selector, I have solve this using below code :
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);
Thanks to Alex Semeniuk
Solution 26 - Android
I end up with this issue by changing the images. Just added extra transparent background in png files. This solution works excellent on all the APIs.
Solution 27 - Android
Maybe it is to late, but I've created utility methods to manage this issue.
Just add this methods to your 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());
}
And use like this:
ViewUtils.setCheckBoxOffset(mAgreeTerms, R.dimen.space_medium);
or like this:
// Be careful with this usage, because it sets padding in pixels, not in dp!
ViewUtils.setCheckBoxOffsetPx(mAgreeTerms, 100f);
Solution 28 - Android
@CoolMind has the nice way but it couldn't add the space at the beginning of checkbox by android:paddingLeft
, instead use this way
<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
should help you
Solution 29 - Android
I think this can help you
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="-30dp"
android:paddingLeft="30dp"
android:drawableLeft="@drawable/check"
/>
Solution 30 - Android
if some one need padding around drawable try this
<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" />
Solution 31 - Android
Instead of adjusting the text for Checkbox, I have done following thing and it worked for me for all the devices.
- In XML, add checkbox and a textview to adjacent to one after another; keeping some distance.
- Set checkbox text size to 0sp.
- Add relative text to that textview next to the checkbox.
Solution 32 - Android
<CheckBox android:drawablePadding="16dip"
- The padding between the drawables and the text.