Android - CheckBox ve metin arasındaki boşluk


256

Bir CheckBox denetimindeki onay kutusu ile ilişkili metin arasına dolgu eklemenin kolay bir yolu var mı?

Yalnızca önde gelen boşlukları ekleyemiyorum, çünkü etiketim çok satırlı.

Olduğu gibi, metin onay kutusuna çok yakın: alternatif metin


1
Basit bir çözüm, metne yer vermek için TextViewwith drawableLeftve use kullanmak drawablePaddingolacaktır. Kodda sadece seçili ve seçili olmayan durumları değiştirin.
Muhammed Babar

Ben sadece çizilebilir ve metin arasındaki boşluğu ayarlamak gerekiyordu android: drawablePadding adlı yeni bir xml özniteliğini fark ettim. Ben denemedim ama bu sorun için google'ın "gerçek sonrası" düzeltme düşünüyorum.
Peri Hartman

Yanıtlar:


333

Kendi sorumu cevaplamaktan nefret ediyorum, ama bu durumda ihtiyacım olduğunu düşünüyorum. Kontrol ettikten sonra @Falmarri cevabı ile doğru yoldaydı. Sorun şu ki Android'in CheckBox kontrolü zaten metni olduğu yerde almak için android: paddingLeft özelliğini kullanıyor.

Kırmızı çizgi, tüm CheckBox öğesinin paddingLeft ofset değerini gösterir

alternatif metin

XML düzenimdeki dolguyu geçersiz kılarsam, düzeni bozar. PaddingLeft = "0" ayarının yaptığı:

alternatif metin

XML'de bunu düzeltemediğiniz anlaşılıyor. Bunu kodda yaptınız. İşte 10dp'lik sabit kodlu bir artış ile snippet'im.

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

Bu, yeşil çizginin dolgudaki artış olduğu aşağıdakileri sağlar. Farklı cihazlar onay kutusu için farklı çekilebilir malzemeler kullanabileceğinden, bu bir değeri kodlamaktan daha güvenlidir.

alternatif metin

GÜNCELLEME - İnsanların aşağıdaki yanıtlarda yakın zamanda bahsettiği gibi, bu davranış Jelly Bean'de (4.2) açıkça değişti. Uygulamanızın hangi sürümde çalıştığını kontrol etmesi ve uygun yöntemi kullanması gerekir.

4.3+ için padding_left ayarını yapmanız yeterlidir. Ayrıntılar için htafoya'nın cevabına bakınız.


108
Kendi sorunuza cevap vermede yanlış bir şey yok - muhtemelen bir başkası bu problemi gelecekte yaşayacaktır ve iyi, kapsamlı bir cevap verdiniz.
AndrewKS

4
Sadece ayarlamanın nesi yanlış paddingLeft="48sp"? Ölçek ve yönlendirmeyi değiştirsem bile burada iyi çalışır. Kodunuz bana bir öğe listesi üzerinde düzensiz dolgu değerleri verdi.
harpo

5
@harpo - Farklı cihaz üreticilerinin onay kutusu için farklı grafikler kullanamayacağının garantisi yoktur, yani sabit kodlu dolgularınız farklı cihazlardaki görsel düzeninizi bozabilir. Geçerli dolguyu okuduğum ve eklediğim için sorun olmayacak, ancak bunu yalnızca bir kez yaptığınızdan emin olmalısınız.
DougW

2
@Blundell - Mutlaka değil. Android'in açık kaynak. Bir cihaz satıcısı, tamamen farklı bir grafikle tamamen farklı bir boyutun yerini alabilir. Nedense böyle şeyler yapmayı severler.
DougW

2
Ne yazık ki, bu çözümü getView()özel Bağdaştırıcıda kullanamazsınız (görünümlerinizi geri dönüştürürseniz), dolgulama sürekli artacaktır. Böyle bir şey kullanmak zorunda Bu sorunu gidermek için: 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); }. Ve sonra PADDINGşişirdiğim her CheckBox için kullanın :check.setPadding(PADDING, check.getPaddingTop() ...
Alex Semeniuk

133

@DougW yanıtı verildiğinde, sürümü yönetmek için yaptığım daha basit, onay kutusu görünümüme ekliyorum:

android:paddingLeft="@dimen/padding_checkbox"

burada dimen iki değer klasöründe bulunur:

değerler

<resources>

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

</resources>

değerler-v17 (4.2 JellyBean)

<resources>

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

</resources>

Ben özel bir kontrol var, en iyi seçim için dps kullanın.


2
Bu şimdiye kadarki en iyi cevap. Bununla birlikte, gerçekten values-v17düzeltme, API 17'de tanıtıldığı gibi olmalıdır (yukarıdaki bazı
icecreamman

Mükemmel bir cevap, sadece eski apis (değerler / dimens) için padding_checkbox'ı 0dip'e (API 10 marjında ​​zaten çok büyük) ve htafoya önerdiği gibi değerler-v17 10dip'e ayarladım.
Yar

70

Kullanım bağlıyor android:drawableLeftyerine android:button. Çizilebilir ve metin kullanımı arasında dolgu ayarlamak için android:drawablePadding. Çekilebilir kullanımı konumlandırmak için 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"
        />

sonuç


1
Merhaba, Bu güzel bir yöntem ama u onay kutusunun varsayılan görüntüsünün ekstra sol kenar boşluğu bcoz olsun dikkat edin .. bunun için herhangi bir çözüm
Code_Life

4
set android:background="@android:color/transparent"ve left margin dissapear
madeuz

2
Yukarıdaki kod radyo düğmelerim için mükemmel çalıştı ve 4.2 OS sınırı boyunca tutarlı. Teşekkürler!
gnichola

1
Bu çok daha yüksek bir sıralamada olmalıdır. @Gnichola'nın dediği gibi, bu Android sürümlerinde çalışıyor ve oldukça temiz bir çözüm. Bir stil oluşturun ve temanızda <item name="android:checkboxStyle">@style/CheckBox</item> şu şekilde atayın: Bu şekilde, stil bir kez tanımlanır ve yalnızca bir kez referans verilir.
Rosomack

1
Ayrıca arka planı null (veya özel bir şey) olarak ayarlayın, aksi takdirde lollipop + tüm görünümü kapsayan büyük bir daire dalgalanma efekti alır. Daha uygun bir dalgalanma koymak için <ripple> etiketlerini kullanarak çizilebilir bir v21 düğmesi kullanabilirsiniz.
Tom

34

Android 4.2 Jelly Bean (API 17), paddingLeft öğesini buttonDrawable'dan (sağ kenar) içeri koyuyor. Ayrıca RTL modu için de çalışır.

4.2 paddingLeft düğmeyi yoksaymadan önce Çizilebilir - CompoundButton görünümünün sol kenarından alındı.

Bunu XML ile çözebilirsiniz - paddingLeft'i buttonDrawable.width + requiredSpace olarak eski androidlerde ayarlayın. Yalnızca API 17 kurulumunda requiredSpace olarak ayarlayın. Örneğin, boyut kaynaklarını kullanın ve değerler-v17 kaynak klasöründe geçersiz kılın.

Değişiklik android.widget.CompoundButton.getCompoundPaddingLeft ();


4
Buradaki tek doğru cevap - sorunu tespit ediyor ve birden fazla ticari uygulamada başarıyla kullandığım basit çözümler sunuyor.
madej

1
XML'de buttonDrawable.width'i nasıl alırsınız veya sabit kodlar alırsınız?
Jared Kells

1
Bu sorunu kaldırarak eski bir kodda çözmeyi başardım android:background="@android:color/transparent".
Sebek

Kabul edilen cevap güzel ve çalışıyor, ancak bu basit ve etkilidir. Bu cevap kabul edilmelidir.
Reaz Murshed

27

Evet, dolgu ekleyerek dolgu ekleyebilirsiniz.

android:padding=5dp


4
Bu gerçekten işe yarıyor ... biraz. Birincisi, tüm dolgu için değil, sadece dolgu Solda gereklidir. Ancak, paddingLeft zaten 40dp civarında bir değere ayarlanmış gibi görünüyor. > 40dp olarak ayarlarsam uzaklaşır, <40dp olarak ayarlarsam onay kutusunun altında hareket eder. Bunu doğru olarak işaretleyeceğim ve başka bir soru açacağım, çünkü bununla ilgili endişelerim var.
DougW

Düzeninizi görmeden hiçbir fikrim yok.
Ekim'de Falmarri

evet çalışmıyor ... özellikle samsung cihazı sorun var.
Ranjith Kumar

1
Dolgu ekleyerek dolgu ekleme okunaklı geliyor!
Sermilion

21

Kodsuz temiz bir tasarım istiyorsanız, şunu kullanın:

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

Hile, rengi saydam olarak ayarlamak android:drawableLeftve için bir değer atamaktır android:drawablePadding. Ayrıca, saydamlık, bu tekniği yan etki olmadan herhangi bir arka plan rengi üzerinde kullanmanıza izin verir - renk uyuşmazlığı gibi.


16

API 17 ve üstü için şunları kullanabilirsiniz:

android: paddingStart = "24dp"

API 16 ve önceki sürümlerde şunları kullanabilirsiniz:

android: paddingLeft = "24dp"


1
Çok iyi bir cevap. Dolgunun onay kutusu ve metin arasındaki boşluğu nasıl vereceğini hayal edemiyorum. Genellikle Sol Dolgu, bileşenin sol anlamına gelir.
Mohamed Ibrahim

14

Benim durumumda XML'de aşağıdaki CheckBox özniteliğini kullanarak bu sorunu çözdüm:

*

robot: paddingLeft = "@ Dimen / activity_horizontal_margin"

*


Çok iyi bir cevap. Dolgunun onay kutusu ve metin arasındaki boşluğu nasıl vereceğini hayal edemiyorum. Genellikle Sol Dolgu, bileşenin sol anlamına gelir.
Mohamed Ibrahim

13

Basit çözüm, bu satırı CheckBox özelliklerine ekleyin , 10dp'yi istediğiniz boşluk değeri ile değiştirin

android:paddingLeft="10dp"

10

Adamları tanımıyorum ama test ettim

<CheckBox android:paddingLeft="8mm" tüm metni değil, metni yalnızca sağa taşır.

Bana yakışıyor.


1
Bunu son zamanlarda denemedim, bu yüzden bunun belirli bir cihazda veya daha yeni bir Android OS sürümünde çalışması kesinlikle mümkündür. Farklı kurulumları test etmenizi şiddetle tavsiye ederim, çünkü bu kesinlikle bu soruyu sorduğum zamanda işe yaramadı.
DougW

Bunun 2.3.3 ve 4.2 arasında farklı davrandığını görüyorum (değişiklik arasında nerede olduğundan emin değilim).
Nate

Şunu mu demek istediniz: dp not mm?
Chrispix

10

Neden Android CheckBox'ı daha iyi dolguya sahip olmak için genişletmiyoruz? Bu şekilde CheckBox'ı her kullandığınızda kodda düzeltmek yerine sabit CheckBox'ı kullanabilirsiniz.

İlk Uzat Onay Kutusu:

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));
    }
}

İkinci olarak normal bir CheckBox oluşturmak yerine xml'nizde genişletilmiş bir CheckBox oluşturun

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

2
OS> 4.2 ise bunu yapmaktan kaçınmak için bir 'if' eklemelisiniz çünkü Jelly Bean'de bunu "düzeltmişlerdir".
Martin Marconcini

1
Aslında> = 4,2 (17).
Aleks N.

6

Ben sadece şu sonuca vardım:

CheckBox'ı geçersiz kıl ve özel bir çekilebilir ürününüz varsa bu yöntemi ekleyin:

@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;
    }

}

veya çekilebilir sistemi kullanıyorsanız:

@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;
    }

}

Cevap için teşekkürler :)


4

Jelly Bean'de bu davranış değişmiş gibi görünüyor. PaddingLeft hilesi ek dolgu ekleyerek metnin çok doğru görünmesini sağlar. Bunu fark eden var mý?


Güncelleme için teşekkürler! Bu konudaki cevabıma bir not ekledim.
DougW

4

Onay işareti ile metin arasındaki boşluk için:

android:paddingLeft="10dp"

Ancak 10dp'den fazla olur, çünkü onay işareti etrafında dolgu (yaklaşık 5dp) bulunur. Dolguyu kaldırmak istiyorsanız Android CheckBox çevresindeki dolguyu kaldırma konusuna bakın :

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

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

@AndrewKS - Test edildi. Beklendiği gibi, bu, onay kutusu ile metin arasında değil, tüm denetime dolgu ekler.
DougW

Metni ayrı bir TextView'de bulundurmak daha iyi olabilir.
AndrewKS

@AndrewKS - Kullanılabilirlik için kötü fikir. Kullanıcının metne dokunmasını ve onay kutusunu seçmesini / seçimini kaldırmasını istiyorum. Ayrıca, bir web sayfasında yaptığınız gibi birçok erişilebilirlik özelliğini bozar.
DougW

Bad idea for usabilityHayır değil. Hem onay kutusunu hem de metin görünümünü doğrusal bir mizanpaja yerleştirin ve bu doğrusal yerleşimi dokunulabilir yapın.
Ekim'de Falmarri

1
-1 Bu cevap, görüntü ve metin arasındaki boşlukla ilgili soruda ortaya çıkan sorunu ele almıyor
David Laing

2

Onay kutusu veya radyo düğmesi için özel görüntü seçiciniz varsa, aşağıdaki gibi aynı düğme ve arka plan özelliğini ayarlamanız gerekir:

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

Arka plan özelliğiyle onay kutusunun veya radyo düğmesi dolgusunun boyutunu kontrol edebilirsiniz.


Hayır, bunu yapmak zorunda değilsiniz. Onay kutusu / radyo düğmesi glifinden farklı bir arka planınız varsa, bu kabul edilemez.
andr

2

xml dosyasında sadece bir parametre olması gerekir

android:paddingLeft="20dp"

2

0dpAndroid 9 API 28'de minHeight ve minWidth'i benim için en temiz ve en doğrudan çözüm olarak ayarlamak :

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


1

Yaptığım şey, (göreli) bir TextViewve bir CheckBoxiçerisine sahip olmak Layout. TextViewGörüntüler Ben kullanıcı görmek istiyorum ve bu metin CheckBoxherhangi bir metin bulunmamaktadır. Bu şekilde, CheckBoxistediğim yerde pozisyon / dolgu ayarlayabilirim .



0

Dolgunuzu bu boyuta eklemek için kullandığınız görüntünün boyutunu almanız gerekir. Android cihazlarda, src'de belirttiğiniz çekilebilirliği alırlar ve daha sonra boyutunu kullanırlar. Özel bir değişken olduğundan ve ona erişemediğiniz alıcı olmadığından. Ayrıca com.android.internal.R.styleable.CompoundButtonunu alamazsınız ve çekilebilir oradan alabilirsiniz.

Bu yüzden kendi stilinizi (yani custom_src) oluşturmanız gerekir veya doğrudan RadioButton uygulamanıza ekleyebilirsiniz:

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

0

Muhtemelen android:buttonmülkünüz için çekilebilir bir seçici kullandığınızdan, aşağıdaki android:constantSize="true"gibi varsayılan bir çekilebilir kalem eklemeniz ve / veya belirtmeniz gerekir :

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

Bundan sonra, android:paddingLeftxml onay kutunuzda özellik belirtmeniz gerekir .

Eksileri:

Düzen düzenleyicide api 16 ve altı ile onay kutusunun altına giden metni alacaksınız, bu durumda önerilen gibi ancak api seviyesi 16 için özel onay kutusu sınıfı oluşturarak düzeltebilirsiniz .

Gerekçe:

StateListDrawable#getIntrinsicWidth()çağrı dahili olarak kullanıldığı için bir hatadır , ancak mevcut durum yoksa ve sabit boyut kullanılmazsa değer CompoundButtondöndürebilir < 0.


0

Bu sorunu aşmak için yapmanız gereken eklemektir android:singleLine="true"için checkBoxandroid xml düzeninde:

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

ve programlı olarak özel bir şey eklenmeyecek.


0

Seçici kendi çizilebilir kullandığımda onay kutusu görüntü çakışan, ben aşağıdaki kodu kullanarak çözdüm:

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'a teşekkürler


0

Sonunda görüntüleri değiştirerek bu sorunla karşılaşıyorum. PNG dosyalarına ekstra şeffaf arka plan ekledim. Bu çözüm tüm API'larda mükemmel çalışır.


0

Belki çok geç, ama bu sorunu yönetmek için yardımcı yöntemler oluşturdum.

Bu yöntemleri araçlarınıza ekleyin:

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());
}

Ve şöyle kullanın:

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

ya da bunun gibi:

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

-1

Checkbox için metni ayarlamak yerine, aşağıdaki şeyleri yaptım ve tüm cihazlar için benim için çalıştı. 1) XML'de, birbiri ardına onay kutusu ve metin görünümü ekleyin; biraz mesafe tutmak. 2) Onay kutusu metin boyutunu 0sp olarak ayarlayın. 3) Bu metin görünümüne onay kutusunun yanındaki göreli metin ekleyin.


-3

<CheckBox android:drawablePadding="16dip" - Çekilebilir malzemeler ve metin arasındaki dolgu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.