Android - Jarak antara Kotak centang dan teks


256

Apakah ada cara mudah untuk menambahkan padding di antara kotak centang di kontrol kotak centang, dan teks yang terkait?

Saya tidak bisa hanya menambahkan spasi, karena label saya multi-baris.

Seperti apa adanya, teks terlalu dekat dengan kotak centang: teks alternatif


1
Solusi sederhana akan menggunakan TextViewdengan drawableLeftdan gunakan drawablePaddinguntuk memberi ruang pada teks. Dalam kode hanya beralih kondisi yang dipilih dan tidak dipilih.
Muhammad Babar

Saya baru saja melihat atribut xml baru yang disebut android: drawablePadding, yang seharusnya mengatur jarak antara drawable dan teks. Saya tidak mencobanya tetapi saya pikir itu perbaikan "setelah-fakta" google untuk masalah ini.
Peri Hartman

Jawaban:


333

Saya benci menjawab pertanyaan saya sendiri, tetapi dalam hal ini saya pikir saya perlu. Setelah memeriksanya, @ Falmarri berada di jalur yang benar dengan jawabannya. Masalahnya adalah bahwa kontrol kotak centang Android sudah menggunakan properti android: paddingLeft untuk mendapatkan teks di mana itu.

Garis merah menunjukkan nilai offset paddingLeft dari seluruh kotak centang

teks alternatif

Jika saya hanya mengganti bantalan itu di tata letak XML saya, itu mengacaukan tata letak. Inilah yang dilakukan pengaturan paddingLeft = "0":

teks alternatif

Ternyata Anda tidak dapat memperbaikinya dalam XML. Anda sudah melakukannya dalam kode. Ini cuplikan saya dengan peningkatan padding hardcoded sebesar 10dp.

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

Ini memberi Anda yang berikut, di mana garis hijau adalah peningkatan padding. Ini lebih aman daripada nilai hardcoding, karena perangkat yang berbeda dapat menggunakan drawables yang berbeda untuk kotak centang.

teks alternatif

UPDATE - Seperti orang baru-baru ini disebutkan dalam jawaban di bawah, perilaku ini tampaknya telah berubah di Jelly Bean (4.2). Aplikasi Anda perlu memeriksa versi mana yang sedang berjalan, dan menggunakan metode yang sesuai.

Untuk 4.3+ itu hanya mengatur padding_left. Lihat jawaban htafoya untuk detailnya.


108
Tidak ada salahnya menjawab pertanyaan Anda sendiri - orang lain mungkin akan memiliki masalah ini di masa depan dan Anda baru saja memberikan jawaban yang baik dan komprehensif.
AndrewKS

4
Apa yang salah dengan pengaturan saja paddingLeft="48sp"? Berfungsi dengan baik di sini, bahkan jika saya mengubah skala dan orientasi. Kode Anda memberi saya nilai padding tidak menentu pada daftar item.
harpo

5
@harpo - Anda tidak memiliki jaminan bahwa produsen perangkat yang berbeda tidak akan menggunakan grafik yang berbeda untuk kotak centang, artinya padding hard-coded Anda dapat merusak tata letak visual Anda pada perangkat yang berbeda. Karena saya membaca padding saat ini dan menambahkannya, itu tidak akan menjadi masalah, tetapi Anda harus memastikan Anda hanya melakukannya sekali.
DougW

2
@ Blundell - Tidak harus. Sumber terbuka Android. Vendor perangkat dapat mengganti grafik yang sama sekali berbeda dengan ukuran yang sama sekali berbeda. Mereka suka melakukan hal-hal seperti itu karena suatu alasan.
DougW

2
Sayangnya, Anda tidak dapat menggunakan solusi ini di getView()Adaptor khusus (jika Anda mendaur ulang tampilan), karena bantalan akan meningkat tanpa henti. Untuk memperbaiki masalah ini saya harus menggunakan sesuatu seperti ini: 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); }. Dan kemudian gunakan PADDINGuntuk setiap Kotak centang saya mengembang:check.setPadding(PADDING, check.getPaddingTop() ...
Alex Semeniuk

133

Diberikan tanggapan @DougW, apa yang saya lakukan untuk mengelola versi lebih sederhana, saya tambahkan ke tampilan kotak centang saya:

android:paddingLeft="@dimen/padding_checkbox"

tempat dimen ditemukan dalam dua folder nilai:

nilai-nilai

<resources>

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

</resources>

values-v17 (4.2 JellyBean)

<resources>

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

</resources>

Saya punya pemeriksaan khusus, gunakan dps untuk pilihan terbaik Anda.


2
Ini adalah jawaban terbaik sejauh ini. meskipun, itu harus benar-benar terjadi values-v17ketika perbaikan diperkenalkan di API 17 (menurut beberapa posting di atas)
icecreamman

Jawaban sempurna, hanya untuk apis yang lebih lama (nilai / dimens) saya mengatur padding_checkbox ke 0dip (pada margin API 10 sudah sangat besar) dan untuk nilai-v17 10dip seperti yang disarankan htafoya.
Yar

70

Gunakan atribut android:drawableLeftalih-alih android:button. Untuk mengatur padding antara drawable dan text use android:drawablePadding. Untuk memposisikan penggunaan yang dapat ditarik 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"
        />

hasil


1
Hai, Ini adalah metode yang bagus tetapi perhatikan bahwa Anda mendapatkan tambahan margin kiri dari gambar default kotak centang .. solusi apa pun untuk itu
Code_Life

4
set android:background="@android:color/transparent"dan margin kiri akan menghilang
madeuz

2
Kode di atas berfungsi dengan baik untuk tombol radio saya, dan konsisten di seluruh batas OS 4.2. Terima kasih!
gnichola

1
Ini harus peringkat jauh lebih tinggi. Seperti yang dikatakan @gnichola, ini berfungsi lintas versi Android dan merupakan solusi yang cukup bersih. Buat gaya dan tentukan dalam tema Anda seperti ini: <item name="android:checkboxStyle">@style/CheckBox</item> Dengan begitu, Anda memiliki gaya yang ditentukan sekali dan direferensikan sekali saja.
Rosomack

1
Juga setel latar belakang ke nol (atau sesuatu yang khusus), jika tidak lollipop + mendapat efek riak lingkaran besar yang mencakup seluruh tampilan. Anda dapat menggunakan tombol v21 yang dapat ditarik menggunakan tag <ripple> untuk memasukkan kembali riak yang lebih sesuai.
Tom

34

Android 4.2 Jelly Bean (API 17) menempatkan teks paddingLeft dari buttonDrawable (ints right edge). Ini juga berfungsi untuk mode RTL.

Sebelum 4.2 paddingLeft mengabaikan buttonDrawable - itu diambil dari tepi kiri tampilan CompoundButton.

Anda dapat menyelesaikannya melalui XML - atur paddingLeft ke buttonDrawable.width + requiredSpace pada android yang lebih lama. Setel ke diperlukanSpace hanya pada API 17 ke atas. Misalnya menggunakan sumber daya dimensi dan menimpa dalam folder sumber daya nilai-v17.

Perubahan itu diperkenalkan melalui android.widget.CompoundButton.getCompoundPaddingLeft ();


4
Ini satu-satunya jawaban yang benar di sini - ini menunjukkan masalah dan memberikan solusi sederhana, yang telah saya gunakan dengan sukses di beberapa aplikasi komersial.
madej

1
Bagaimana Anda mendapatkan buttonDrawable.width dalam XML atau Anda membuat kode keras?
Jared Kells

1
Saya berhasil memperbaiki masalah ini dalam kode lama dengan menghapus android:background="@android:color/transparent".
Sebek

Jawaban yang diterima bagus dan berfungsi, tetapi yang ini sederhana dan efektif. Ini harus diterima jawaban.
Reaz Murshed

27

Ya, Anda dapat menambahkan padding dengan menambahkan padding.

android:padding=5dp


4
Ini sebenarnya berfungsi ... semacam. Untuk satu, hanya paddingLeft yang dibutuhkan, tidak semua padding. Namun, sepertinya paddingLeft sudah diset ke nilai sekitar 40dp. Jika saya mengaturnya> 40dp itu bergerak menjauh, jika saya mengaturnya <40dp bergerak di bawah kotak centang. Saya akan menandai ini sebagai benar dan membuka pertanyaan lain, karena saya khawatir tentang itu.
DougW

Yah saya tidak tahu tanpa melihat tata letak Anda.
Falmarri

ya tidak berfungsi..terutama perangkat samsung saya mendapat masalah.
Ranjith Kumar

1
Menambahkan padding dengan menambahkan padding terdengar sah!
Sermilion

21

Jika Anda ingin desain yang bersih tanpa kode, gunakan:

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

Triknya adalah mengatur warna menjadi transparan untuk android:drawableLeftdan memberikan nilai android:drawablePadding. Selain itu, transparansi memungkinkan Anda untuk menggunakan teknik ini pada warna latar belakang apa pun tanpa efek samping - seperti ketidakcocokan warna.


16

API 17 dan di atasnya, Anda dapat menggunakan:

android: paddingStart = "24dp"

API 16 dan di bawah, Anda dapat menggunakan:

android: paddingLeft = "24dp"


1
Jawaban yang sangat bagus Saya tidak bisa membayangkan bagaimana padding akan memberi ruang antara kotak centang dan teks. Biasanya Padding Left berarti kiri komponen.
Mohamed Ibrahim

14

Dalam kasus saya, saya memecahkan masalah ini menggunakan atribut CheckBox berikut ini di XML:

*

android: paddingLeft = "@ dimen / activity_horizontal_margin"

*


Jawaban yang sangat bagus Saya tidak bisa membayangkan bagaimana padding akan memberi ruang antara kotak centang dan teks. Biasanya Padding Left berarti kiri komponen.
Mohamed Ibrahim

13

Solusi sederhana, tambahkan baris ini di properti CheckBox , ganti 10dp dengan nilai spasi yang Anda inginkan

android:paddingLeft="10dp"

10

Saya tidak kenal teman-teman, tapi saya diuji

<CheckBox android:paddingLeft="8mm" dan hanya memindahkan teks ke kanan, bukan seluruh kontrol.

Ini cocok untuk saya.


1
Saya belum mencoba ini baru-baru ini, jadi mungkin saja ini bekerja pada perangkat tertentu, atau versi OS Android yang lebih baru. Saya akan sangat menyarankan Anda menguji pada pengaturan yang berbeda, karena ini pasti tidak berfungsi pada saat saya mengajukan pertanyaan ini.
DougW

Saya melihat ini berperilaku berbeda antara 2.3.3 dan 4.2 (tidak yakin di mana di antara perubahan terjadi).
Nate

Apakah maksud Anda dp bukan mm?
Chrispix

10

Mengapa tidak memperpanjang Kotak Centang Android agar memiliki lapisan yang lebih baik sebagai gantinya. Dengan begitu alih-alih harus memperbaikinya dalam kode setiap kali Anda menggunakan Kotak Centang, Anda hanya dapat menggunakan Kotak Centang yang diperbaiki.

Kotak Perluas Pertama:

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

Kedua di xml Anda alih-alih membuat Kotak Centang normal, buatlah kotak yang diperluas

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

2
Anda harus menambahkan 'jika' untuk menghindari melakukan itu jika OS> 4.2 karena di Jelly Bean mereka "memperbaiki" ini.
Martin Marconcini

1
Sebenarnya> = 4.2 (17).
Aleks N.

6

Saya baru saja menyimpulkan ini:

Ganti Kotak centang dan tambahkan metode ini jika Anda memiliki drawable yang dapat disesuaikan:

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

}

atau ini jika Anda menggunakan sistem 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;
    }

}

Terima kasih atas jawabannya :)


4

Perilaku ini tampaknya telah berubah dalam Jelly Bean. Trik paddingLeft menambahkan padding tambahan, membuat teks terlihat terlalu jauh ke kanan. Adakah yang memperhatikan itu?


Terima kasih atas pembaruannya! Saya telah menambahkan catatan untuk jawaban saya tentang ini.
DougW

4

Untuk ruang antara tanda centang dan penggunaan teks:

android:paddingLeft="10dp"

Tetapi menjadi lebih dari 10dp, karena tanda centang berisi padding (sekitar 5dp) di sekitar. Jika Anda ingin menghapus bantalan, lihat Cara menghapus bantalan di Android Kotak Centang :

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 - Diuji. Seperti yang diharapkan, ini menambahkan padding ke seluruh kontrol, bukan di antara kotak centang dan teks.
DougW

Anda mungkin lebih baik memiliki teks dalam TextView yang terpisah.
AndrewKS

@AndrewKS - Gagasan buruk untuk kegunaan. Saya ingin pengguna dapat menyentuh teks dan memilih / tidak memilih kotak centang. Ini juga merusak banyak fitur aksesibilitas, dengan cara yang sama seperti jika Anda melakukannya di halaman web.
DougW

Bad idea for usabilityBukan itu. Letakkan kedua kotak centang dan tampilan teks dalam tata letak linier dan buat agar linearlayout tersentuh.
Falmarri

1
-1 Jawaban ini tidak membahas masalah yang diajukan dalam pertanyaan, yaitu tentang kesenjangan antara gambar dan teks
David Laing

2

Jika Anda memiliki pemilih gambar khusus untuk kotak centang atau radiobutton, Anda harus mengatur properti tombol dan latar belakang yang sama seperti ini:

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

Anda dapat mengontrol ukuran kotak centang atau bantalan tombol radio dengan properti latar belakang.


Tidak, Anda tidak harus melakukan ini. Ini tidak dapat diterima jika Anda memiliki latar belakang khusus yang berbeda dari kotak centang / mesin terbang glyph.
andr

2

hanya Anda yang perlu memiliki satu parameter dalam file xml

android:paddingLeft="20dp"

2

Mengatur minHeight dan minWidth menjadi 0dpsolusi terbersih dan terarah bagi saya di 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" />


1

Apa yang saya lakukan, adalah memiliki TextViewdan CheckBoxdi dalam (Relatif) Layout. The TextViewmenampilkan teks yang saya ingin pengguna untuk melihat, danCheckBox tidak memiliki teks. Dengan begitu, saya bisa mengatur posisi / padding dari CheckBoxmana pun saya mau.


1

Saya memiliki masalah yang sama dengan mini Galaxy S3 (android 4.1.2) dan saya hanya membuat kotak centang ubahsuaian saya memperpanjang AppCompatCheckBox bukannya CheckBox. Sekarang ini berfungsi dengan baik.


0

Anda perlu mendapatkan ukuran gambar yang Anda gunakan untuk menambahkan padding Anda ke ukuran ini. Di Android internal, mereka mendapatkan drawable yang Anda tentukan di src dan gunakan ukurannya setelahnya. Karena ini adalah variabel pribadi dan tidak ada getter yang tidak dapat Anda akses. Anda juga tidak bisa mendapatkan com.android.internal.R.styleable.CompoundButton dan dapatkan gambarnya dari sana.

Jadi, Anda perlu membuat style Anda sendiri (yaitu custom_src) atau Anda dapat menambahkannya langsung dalam implementasi RadioButton Anda:

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

Karena Anda mungkin menggunakan pemilih yang dapat ditarik untuk android:buttonproperti Anda, Anda perlu menambahkan android:constantSize="true"dan / atau menentukan drawable default seperti ini:

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

Setelah itu Anda perlu menentukan android:paddingLeft atribut di kotak centang xml Anda.

Cons:

Di editor tata letak Anda akan teks masuk di bawah kotak centang dengan api 16 dan di bawah, dalam hal ini Anda dapat memperbaikinya dengan membuat Anda kelas kotak centang kustom seperti yang disarankan tetapi untuk api level 16.

Alasan:

itu adalah bug karena StateListDrawable#getIntrinsicWidth()panggilan digunakan secara internal, CompoundButtontetapi dapat mengembalikan < 0nilai jika tidak ada kondisi saat ini dan tidak ada ukuran konstan yang digunakan.


0

Semua harus Anda lakukan untuk mengatasi masalah ini adalah dengan menambahkan android:singleLine="true"ke checkBoxdalam tata letak xml android Anda:

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

dan tidak ada yang istimewa yang akan ditambahkan secara pemrograman.


0

Gambar kotak centang tumpang tindih ketika saya menggunakan drawables saya sendiri dari pemilih, saya telah menyelesaikan ini menggunakan kode di bawah ini:

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

Terima kasih untuk Alex Semeniuk


0

Saya berakhir dengan masalah ini dengan mengubah gambar. Baru saja menambahkan latar belakang ekstra transparan dalam file png. Solusi ini berfungsi sangat baik di semua API.


0

Mungkin sudah terlambat, tetapi saya telah membuat metode utilitas untuk mengelola masalah ini.

Cukup tambahkan metode ini ke utilitas Anda:

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

Dan gunakan seperti ini:

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

atau seperti ini:

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

-1

Alih-alih menyesuaikan teks untuk Kotak Centang, saya telah melakukan hal berikut dan itu bekerja untuk saya untuk semua perangkat. 1) Dalam XML, tambahkan kotak centang dan tampilan teks yang berdekatan satu demi satu; menjaga jarak. 2) Atur ukuran teks kotak centang ke 0sp. 3) Tambahkan teks relatif ke tampilan teks di sebelah kotak centang.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.