Imagen de casilla de verificación personalizada android

182

¿Hay una manera fácil de usar una imagen personalizada para una casilla de verificación? Estoy buscando duplicar el comportamiento "destacado" de gmail. Entonces quiero tener una casilla de verificación que, cuando está marcada, es una estrella rellena. Y cuando no está marcado es una estrella vacía. ¿Tengo que usar una vista de imagen y hacer mi propia lógica?

Falmarri
fuente

Respuestas:

128

Las casillas de verificación que son elementos secundarios de Button pueden darle a su casilla de verificación una imagen de fondo con varios estados como se describe aquí , en "Estilo de botón":

... y ejemplificado aquí :

Vaquero
fuente
26
Gracias, en realidad encontré exactamente lo que necesitaba aquí it-ride.blogspot.com/2010/04/… pero habría tenido que hacerlo a su manera si hubiera querido una imagen personalizada real = P
Falmarri
2
Gracias. Exactamente lo que estaba buscando: descubrí todo el estado, pero configuré android: background en lugar de android: button y terminé con 2 botones. Ahora todo funciona bien.
Artem Russakovskii
1
-1. ¡La android:buttonsolución a continuación es mucho mejor que usar el atributo de fondo!
Orabîg
8
@ Orabîg: Este voto negativo está mal. La pregunta está perfectamente respondida ("Imagen de casilla de verificación personalizada"). El hecho de que exista un acceso directo para este botón destacado en particular no invalida esta respuesta.
antes del
Si bien esta es una publicación antigua, me gustaría agregar que Android Studio también usa el método android: button = "@ android: drawable / btn_star"
Angry 84
289

Cree un selector de casillas de dibujo:

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

Asegúrese de que su casilla de verificación sea así 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" />
Mohamed Hisham Ibn Hanifa
fuente
¿En qué registro especificas este selector? ¿Dentro del archivo XML en el que también está especificando CheckBox?
Tom Hammond
Tom: cree su selector en la carpeta dibujable y marque la casilla en la carpeta de diseño
Mohamed Hisham Ibn Hanifa
Tuve que cambiar 'botón' por 'fondo' en el CheckBox
Francisco Corrales Morales
Para el relleno, consulte stackoverflow.com/questions/4037795/…
PiTheNumber
2
He actualizado mi proyecto a Android x después de eso, no pude personalizar mi casilla de verificación como dijiste antes del nivel 21 de la API y Android: el botón no funciona.
Misagh Aghakhani
44

Copie el archivo btn_check.xml de android-sdk / plataformas / android - # / data / res / drawable en la carpeta dibujable de su proyecto y cambie los estados de imagen 'on' y 'off' a sus imágenes personalizadas.

Entonces tu xml solo necesitará android:button="@drawable/btn_check"

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

Si desea usar diferentes iconos de Android predeterminados, puede usar android:button="@android:drawable/..."

HERIDOSStevenJones
fuente
2
Mal consejo. Los iconos pueden cambiar de una versión a otra y pueden desaparecer. Si realmente le gusta el icono predeterminado, puede obtenerlo de las fuentes.
Korniltsev Anatoly
¿Está diciendo que hacer referencia a los iconos predeterminados directamente a través de "@android: drawable / ..." es una mala idea, o este proceso por completo?
WOUNDEDStevenJones
2
Ejemplo: la referencia a iconos de holo bloqueará su aplicación en dispositivos anteriores al panal. Es realmente difícil mantener y depurar tales problemas. Por lo tanto, generalmente copio no solo xml sino también las imágenes para estar cien por ciento seguro de que se encontrarán los recursos. Además, esto es muy importante para garantizar que la IU se vea igual en todos los dispositivos.
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" />
Rahul
fuente
1
Alguna explicación ayudaría a los nuevos usuarios a comprender cómo su código resuelve el problema.
Brian Tompsett - 汤 莱恩
7

Si tiene código fuente abierto de Android, puede encontrar la definición de estilos en:
src / frameworks / base / core / res / res / values

<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>
achellies
fuente
4

Intentalo -

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

Agregue este atributo -

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

Usar como -

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

Arreglará todos tus problemas.

Neo
fuente
Faltan los métodos onSaveInstanceState()y onRestoreInstanceState(), creo que el estado verificado se perdería en la rotación
EpicPandaForce
2

Otra opción es usar un ToggleButton con fondo nulo y un botón personalizado.

A continuación se muestra un ejemplo que incluye un selector para el color del texto también.

<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>
androidevil
fuente
2

Si está utilizando adaptadores personalizados android:focusable="false"y android:focusableInTouchMode="false"está seguro de hacer clic en los elementos de la lista mientras usa la casilla de verificación.

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

En 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>
Chitransh Goud
fuente
1

Si usa androidx.appcompat: appcompat y desea un diseño personalizado (de tipo selectorcon android:state_checked) para trabajar en versiones de plataforma antiguas además de nuevas versiones de plataforma, debe usar

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

en vez de

    <CheckBox
        android:button="@drawable/..."
Enselico
fuente
1

Basado en las respuestas de Enselic y Rahul.

Funciona para mí (antes y después de 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" />
alexrnov
fuente