Immagine della casella di controllo personalizzata android


182

Esiste un modo semplice per utilizzare un'immagine personalizzata per una casella di controllo? Sto cercando di duplicare il comportamento "speciale" di Gmail. Quindi voglio avere una casella che, quando selezionata, è una stella piena. E quando deselezionato è una stella vuota. Devo usare una visualizzazione di immagini e fare la mia logica da solo?

Risposte:


128

Le caselle di controllo essendo figli di Button puoi semplicemente dare alla tua casella di controllo un'immagine di sfondo con diversi stati come descritto qui , sotto "Stile pulsante":

... ed esemplificato qui :


26
Grazie, in realtà ho trovato esattamente quello che mi serviva qui it-ride.blogspot.com/2010/04/... ma avrei dovuto fare a modo tuo, se volevo una vera e propria immagine personalizzata = P
Falmarri

2
Grazie. Esattamente quello che stavo cercando - ho capito tutto sullo stato ma ho impostato android: background invece di android: button e invece ho finito con 2 pulsanti. Ora funziona tutto bene.
Artem Russakovskii,

1
-1. La android:buttonsoluzione seguente è molto meglio dell'uso dell'attributo in background!
Orabîg,

8
@ Orabîg: questo downvote è sbagliato. La domanda ha una risposta perfetta ("Immagine della casella di controllo personalizzata"). Il fatto che esista un collegamento per questo particolare pulsante a stella non invalida questa risposta.
Il

Anche se questo forse è un vecchio post, vorrei aggiungere che Android Studio utilizza anche il metodo android: button = "@ android: drawable / btn_star"
Angry 84

289

Crea un selettore di casella estraibile:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/checkbox" 
          android:state_checked="false"/>
    <item android:drawable="@drawable/checkboxselected" 
          android:state_checked="true"/>
    <item android:drawable="@drawable/checkbox"/>    
</selector>

Assicurati che la tua casella di controllo sia così android:button="@drawable/checkbox_selector"

<CheckBox
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:button="@drawable/checkbox_selector"
    android:text="CheckBox"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="@color/Black" />

In quale record specifichi questo selettore? All'interno del file XML stesso in cui si sta specificando anche CheckBox?
Tom Hammond,

Tom: crea il tuo selettore nella cartella estraibile e la casella di controllo nella cartella del layout
Mohamed Hisham Ibn Hanifa,

Ho dovuto cambiare "pulsante" per "sfondo" nel CheckBox
Francisco Corrales Morales il


2
Ho aggiornato il mio progetto ad Android X dopo che non ho potuto personalizzare la mia casella di controllo come hai detto prima di API 21 e Android: il pulsante non funziona.
Misagh Aghakhani,

44

Copia btn_check.xml da android-sdk / platform / android - # / data / res / drawable nella cartella disegnabile del tuo progetto e modifica gli stati immagine 'on' e 'off' nelle tue immagini personalizzate.

Quindi il tuo XML avrà solo bisogno android:button="@drawable/btn_check"

<CheckBox
    android:button="@drawable/btn_check"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="true" />

Se si desidera utilizzare diverse icone Android predefinite, è possibile utilizzare android:button="@android:drawable/..."


2
Cattivo consiglio. Le icone possono essere cambiate da versione a versione e possono scomparire del tutto. Se ti piace davvero l'icona predefinita, puoi prenderla dalle fonti.
Korniltsev Anatoly il

Stai dicendo che fare riferimento alle icone predefinite direttamente tramite "@android: drawable / ..." è una cattiva idea o questo processo è del tutto?
WOUNDEDStevenJones,

2
Esempio: il riferimento alle icone di Holo causerà l'arresto anomalo dell'app su dispositivi pre-nido d'ape. È davvero difficile mantenere ed eseguire il debug di tali problemi. Quindi di solito copio non solo xml ma anche le immagini per essere hundreed percento sicuro che le risorse saranno trovate. Inoltre, questo è molto importante per garantire che l'interfaccia utente sia la stessa su tutti i dispositivi.
Korniltsev Anatoly,

15

res / drawable / day_selector.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" >
        <item android:drawable="@drawable/dayselectionunselected"
              android:state_checked="false"/>
        <item android:drawable="@drawable/daysselectionselected"
              android:state_checked="true"/>
        <item android:drawable="@drawable/dayselectionunselected"/>
    </selector>

res / layout / my_layout.xml

<CheckBox
    android:id="@+id/check"
    android:layout_width="39dp"
    android:layout_height="39dp"
    android:background="@drawable/day_selector"
    android:button="@null"
    android:gravity="center"
    android:text="S"
    android:textColor="@color/black"
    android:textSize="12sp" />

1
Alcune spiegazioni potrebbero aiutare i nuovi utenti a capire come il codice risolve il problema.
Brian Tompsett - 莱恩 莱恩

7

Se hai il codice open source Android, puoi trovare la definizione degli stili in:
src / frameworks / base / core / res / res / valori

<style name="Widget.CompoundButton.CheckBox">
    <item name="android:background">
        @android:drawable/btn_check_label_background
    </item>
    <item name="android:button">
        ?android:attr/listChoiceIndicatorMultiple
    </item>
</style>

4

Provalo -

package com;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;



public class CheckBoxImageView extends ImageView implements View.OnClickListener {
    boolean checked;
    int defImageRes;
    int checkedImageRes;
    OnCheckedChangeListener onCheckedChangeListener;

    public CheckBoxImageView(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        init(attr, defStyle);
    }

    public CheckBoxImageView(Context context, AttributeSet attr) {
        super(context, attr);
        init(attr, -1);
    }

    public CheckBoxImageView(Context context) {
        super(context);
    }

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
        setImageResource(checked ? checkedImageRes : defImageRes);
    }

    private void init(AttributeSet attributeSet, int defStyle) {
        TypedArray a = null;
        if (defStyle != -1)
            a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CheckBoxImageView, defStyle, 0);
        else
            a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CheckBoxImageView);
        defImageRes = a.getResourceId(0, 0);
        checkedImageRes = a.getResourceId(1, 0);
        checked = a.getBoolean(2, false);
        a.recycle();
        setImageResource(checked ? checkedImageRes : defImageRes);
        setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        checked = !checked;
        setImageResource(checked ? checkedImageRes : defImageRes);
        onCheckedChangeListener.onCheckedChanged(this, checked);
    }

    public void setOnCheckedChangeListener(OnCheckedChangeListener onCheckedChangeListener) {
        this.onCheckedChangeListener = onCheckedChangeListener;
    }

    public static interface OnCheckedChangeListener {
        void onCheckedChanged(View buttonView, boolean isChecked);
    }
}

Aggiungi questo attrib -

<declare-styleable name="CheckBoxImageView">
        <attr name="default_img" format="integer"/>
        <attr name="checked_img" format="integer"/>
        <attr name="checked" format="boolean"/>
</declare-styleable>

Usa come -

 <com.adonta.ziva.consumer.wrapper.CheckBoxImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/checkBox"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="true"
        android:padding="5dp"
        app:checked_img="@drawable/check_box_checked"
        app:default_img="@drawable/check_box" />

Risolverà tutti i tuoi problemi.


Manca il metodo onSaveInstanceState()e onRestoreInstanceState(), penso che lo stato controllato andrebbe perso con la rotazione
EpicPandaForce,

2

Un'altra opzione è quella di utilizzare un ToggleButton con sfondo null e un pulsante personalizzato.

Di seguito un esempio che include anche un selettore per il colore del testo.

<ToggleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:button="@drawable/toggle_selector"
    android:background="@null"
    android:paddingLeft="10dp"
    android:layout_centerHorizontal="true"
    android:gravity="center"
    android:textColor="@drawable/toggle_text"
    android:textOn="My on state"
    android:textOff="My off state" />

toggle_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_checked="true"
        android:drawable="@drawable/state_on" />

    <item
        android:drawable="@drawable/state_off" />

</selector>

toggle_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_checked="true"
        android:color="@color/app_color" />

    <item
        android:color="@android:color/darker_gray" />

</selector>

2

Se si utilizzano adattatori personalizzati di android:focusable="false"e android:focusableInTouchMode="false"sono nessesury per rendere selezionabili gli elementi dell'elenco mentre si utilizza la casella di controllo.

<CheckBox
        android:id="@+id/checkbox_fav"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:button="@drawable/checkbox_layout"/>

In drawable> checkbox_layout.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/uncked_checkbox"
        android:state_checked="false"/>
    <item android:drawable="@drawable/selected_checkbox"
        android:state_checked="true"/>
    <item android:drawable="@drawable/uncked_checkbox"/>
</selector>

1

Se usi androidx.appcompat: appcompat e vuoi un drawable personalizzato (di tipo selectorcon android:state_checked) per lavorare su vecchie versioni della piattaforma oltre alle nuove versioni della piattaforma, devi usare

    <CheckBox
        app:buttonCompat="@drawable/..."

invece di

    <CheckBox
        android:button="@drawable/..."

1

Basato sulle risposte di Enselic e Rahul.

Funziona per me (prima e dopo l'API 21):

<CheckBox
    android:id="@+id/checkbox"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:text=""
    android:gravity="center"

    android:background="@drawable/checkbox_selector"
    android:button="@null"
    app:buttonCompat="@null" />
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.