Чи є простий спосіб додати прокладку між прапором у контролі CheckBox та пов'язаним текстом?
Я не можу просто додати провідні пробіли, оскільки мітка є багаторядковою.
Так, текст є занадто близьким до прапорця:
Чи є простий спосіб додати прокладку між прапором у контролі CheckBox та пов'язаним текстом?
Я не можу просто додати провідні пробіли, оскільки мітка є багаторядковою.
Так, текст є занадто близьким до прапорця:
Відповіді:
Я ненавиджу відповідати на власне запитання, але в цьому випадку я думаю, що мені потрібно. Перевіривши це, @Falmarri був на правильному шляху зі своєю відповіддю. Проблема полягає в тому, що контроль CheckBox Android вже використовує властивість android: paddingLeft, щоб отримати текст там, де він є.
Червона лінія показує значення зміщення paddingLeft для всієї CheckBox
Якщо я просто перекрию цю підкладку в моєму макеті XML, це зіпсує макет. Ось що робить paddingLeft = "0":
Виявляється, ви не можете виправити це в 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());
Це дає вам наступне, де зеленою лінією є збільшення підкладки. Це безпечніше, ніж значення жорсткого кодування, оскільки різні пристрої можуть використовувати різні чертежі для прапорця.
ОНОВЛЕННЯ - Як люди нещодавно згадували у відповідях нижче, ця поведінка, очевидно, змінилася в Jelly Bean (4.2). Ваш додаток повинен перевірити, на якій версії працює його програма, і використовувати відповідний метод.
Для версії 4.3+ це просто встановлення padding_left. Деталі див. У відповіді htafoya.
paddingLeft="48sp"
? Тут чудово працює, навіть якщо я міняю масштаб та орієнтацію. Ваш код дав мені помилкові значення прокладки над списком елементів.
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); }
. А потім використовувати PADDING
для кожного надувного я CheckBox:check.setPadding(PADDING, check.getPaddingTop() ...
З огляду на @DougW відповідь, що я роблю, щоб керувати версією, простіше, я додаю до перегляду прапорець:
android:paddingLeft="@dimen/padding_checkbox"
де розмір знаходиться у двох папках значень:
значення
<resources>
<dimen name="padding_checkbox">0dp</dimen>
</resources>
значення-v17 (4,2 JellyBean)
<resources>
<dimen name="padding_checkbox">10dp</dimen>
</resources>
У мене є спеціальна перевірка, використовуйте dps для вашого найкращого вибору.
values-v17
так, як виправлення було введено в API 17 (згідно з деякими публікаціями вище)
Використовуйте атрибут 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"
/>
android:background="@android:color/transparent"
і лівий запас зникне
<item name="android:checkboxStyle">@style/CheckBox</item>
Таким чином, ви визначили стиль один раз і посилаєтесь лише один раз.
Android 4.2 Jelly Bean (API 17) ставить текстові накладки ліворуч від кнопкиDravable (ints right edge). Він також працює в режимі RTL.
Перед 4.2 paddingLeft ігнорував кнопкуDravable - це було зроблено з лівого краю подання CompoundButton.
Ви можете вирішити це за допомогою XML - встановіть paddingLeft на buttonDravable.width + mustSpace на старих андроїдах. Встановіть його на mustSpace лише в API 17 up. Наприклад, використовуйте параметри ресурсів та замініть параметр у папці значень-v17.
Зміна була введена через android.widget.CompoundButton.getCompoundPaddingLeft ();
android:background="@android:color/transparent"
.
Так, ви можете додати прокладку, додавши прокладку.
android:padding=5dp
Якщо ви хочете охайний дизайн без кодів, використовуйте:
<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
. Також прозорість дозволяє використовувати цю техніку для будь-якого кольору фону без побічного ефекту - як невідповідність кольорів.
API 17 і вище, ви можете використовувати:
android: paddingStart = "24dp"
API 16 і нижче, ви можете використовувати:
android: paddingLeft = "24dp"
У моєму випадку я вирішив цю проблему, використовуючи наступний атрибут CheckBox у XML:
*
android: paddingLeft = "@ dimen / activity_horizontal_margin"
*
Просте рішення, додайте цей рядок у властивості CheckBox , замініть 10dp на потрібне значення інтервалу
android:paddingLeft="10dp"
Хлопці не знаю, але я протестував
<CheckBox android:paddingLeft="8mm"
і лише переміщує текст праворуч, не весь контроль.
Мені це добре підходить.
Чому б просто не розширити Android CheckBox, щоб натомість мати кращі накладки. Таким чином, замість того, щоб фіксувати його в коді кожного разу, коли ви використовуєте CheckBox, ви можете просто використовувати фіксований CheckBox замість цього.
Перший розширений 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));
}
}
По-друге, у вашому xml замість створення звичайного CheckBox створіть розширений
<com.whatever.CheckBoxWithPaddingFix
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello there" />
Я щойно зробив висновок з цього приводу:
Замініть 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;
}
}
Дякую за відповідь :)
Пробіл між галочкою та текстом використовується:
android:paddingLeft="10dp"
Але він стає більше 10dp, тому що галочка містить набивання (близько 5dp) навколо. Якщо ви хочете видалити прокладки, перегляньте розділ Як видалити прокладки навколо Android CheckBox :
android:paddingLeft="-5dp"
android:layout_marginStart="-5dp"
android:layout_marginLeft="-5dp"
// or android:translationX="-5dp" instead of layout_marginLeft
<CheckBox
android:paddingRight="12dip" />
Bad idea for usability
Ні це не так. Поставте і прапорець, і перегляд тексту в лінійному макеті, і зробіть це лінійне розташування дотичним.
Якщо у вас є спеціальний перемикач зображень для прапорця або радіо кнопки, ви повинні встановити таку ж властивість кнопок і фонів, як ця:
<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" />
Ви можете керувати розміром прапорця або набивання радіо кнопок із властивістю фону.
Якщо ви створюєте спеціальні кнопки, наприклад, див. Підручник із зміни вигляду
Потім просто збільшити ширину btn_check_label_background.9.png, додавши ще один або два стовпчики прозорих пікселів у центрі зображення; залиште 9-латові маркери такими, якими вони є.
У мене була така ж проблема з Galaxy S3 mini (android 4.1.2), і я просто зробив свій власний прапорець розширити AppCompatCheckBox замість CheckBox. Зараз це прекрасно працює.
Вам потрібно отримати розмір зображення, яке ви використовуєте, щоб додати ваші набивки до цього розміру. У внутрішніх системах Android вони отримують вказаний у src графічний малюнок, а потім використовують його розмір. Оскільки це приватна змінна, і немає користувачів, до яких ви не можете отримати доступ. Крім того, ви не можете отримати com.android.internal.R.styleable.CompoundButton і отримати звідти доступний файл.
Отже, вам потрібно створити свій власний стиль (наприклад, 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;
}
}
Оскільки ви, ймовірно, використовуєте селектор, що витягується, для вашої 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>
Після цього потрібно вказати android:paddingLeft
атрибут у вашому прапорці xml.
Мінуси:
У редакторі макета ви вкажете текст, який знаходиться під прапором з api 16 і нижче, і в цьому випадку ви можете це виправити, створивши для вас спеціальний клас прапорця, як запропоновано, але для api рівня 16.
Обгрунтування:
це помилка, оскільки StateListDrawable#getIntrinsicWidth()
виклик використовується внутрішньо, CompoundButton
але він може повернути < 0
значення, якщо немає поточного стану та не використовується постійний розмір.
Все, що вам потрібно зробити, щоб подолати цю проблему - це додати android:singleLine="true"
до checkBox
вашого xml-макета Android:
<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);
Дякую Олексію Семенюку
Я закінчую це питання, змінюючи зображення. Просто додано додатковий прозорий фон у png-файлах. Це рішення чудово працює на всіх API.
Можливо, вже пізно, але я створив корисні методи управління цією проблемою.
Просто додайте ці методи до своїх утиліт:
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);
Замість того, щоб коригувати текст для Checkbox, я зробив наступне, і це працювало для мене на всіх пристроях. 1) у XML додайте прапорець та перегляд тексту, що прилягають один до одного; зберігаючи деяку відстань. 2) Установіть розмір тексту прапорця на 0sp. 3) Додайте відносний текст до цього перегляду тексту поруч із прапором.
<CheckBox android:drawablePadding="16dip"
- Прокладка між малюнком і текстом.
TextView
зdrawableLeft
і використовувати ,drawablePadding
щоб дати місце для тексту. У коді просто перемикайте вибрані та невибрані стани.