Custom checkbox image android
Asked Answered
E

12

194

Is there an easy way to use a custom image for a checkbox? I'm looking to duplicate the "starred" behavior of gmail. So I want to have a checkbox that, when checked, is a filled in star. And when unchecked is an empty star. Do I have to use an imageview and do my own logic myself?

Ethical answered 19/10, 2010 at 5:7 Comment(0)
P
129

Checkboxes being children of Button you can just give your checkbox a background image with several states as described here, under "Button style":

...and exemplified here:

Popish answered 19/10, 2010 at 6:23 Comment(8)
Thanks, I actually found exactly what I needed here it-ride.blogspot.com/2010/04/… but I would have had to do it your way if I wanted a real custom image =PEthical
Thank you. Exactly what I've been looking for - I've figured out the whole state thing but I've been setting android:background instead of android:button and ended up with 2 buttons instead. Now it all works well.Married
-1. The android:button solution below is much better than using background attribute !Fin
@Orabîg: This downvote is wrong. The question is perfectly answered ("Custom checkbox image"). The fact that a shortcut exists for this particular starred-button does not invalidate this answer.Acculturate
While this maybe an old post, would like to add that Android studio also uses the android:button="@android:drawable/btn_star" methodNapoleonnapoleonic
How to give width and height to the bitmap in the selector once you specify android:button?Moslem
Note that if you use the button attribute, it will not scale a background image. If you use a background attribute instead, and set android:button=@null, your background will scale to the size of the checkboxAmbrogio
adding bare links is discouraged, please elaborateWhomp
C
316

Create a drawable checkbox selector:

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

Make sure your checkbox is like this 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" />
Cyanine answered 15/7, 2013 at 5:46 Comment(9)
What record do you specify this selector in? Within the XML file itself where you're specifying the CheckBox as well?Aundreaaunson
Tom: create your selector in drawable folder and checkbox in layout folderCyanine
I had to change ´button´ for ´background´ in the CheckBoxKendrickkendricks
For padding see #4038295Interceptor
What if I have many checkboxes with diff. images to show on checking/unchecking the checkbox? How can I pass a parameter to the xml file? Or is there a alternative? I know we can create a seperate checkbox_selector for each but is there a better way?Alicyclic
+1 for android:button I wanted a custom background so I used android:button="@android:color/transparent"Rutty
I have upgraded my project to android x after that I could not customize my checkbox as you said before api level 21 and android:button not works.Procurator
I tried this, and realized <item android:drawable="@drawable/checkbox"/> this is not needed and also takes precedence over check state as true.Nolasco
@MisaghAghakhani See my answer below for the solution to thatHistolysis
P
129

Checkboxes being children of Button you can just give your checkbox a background image with several states as described here, under "Button style":

...and exemplified here:

Popish answered 19/10, 2010 at 6:23 Comment(8)
Thanks, I actually found exactly what I needed here it-ride.blogspot.com/2010/04/… but I would have had to do it your way if I wanted a real custom image =PEthical
Thank you. Exactly what I've been looking for - I've figured out the whole state thing but I've been setting android:background instead of android:button and ended up with 2 buttons instead. Now it all works well.Married
-1. The android:button solution below is much better than using background attribute !Fin
@Orabîg: This downvote is wrong. The question is perfectly answered ("Custom checkbox image"). The fact that a shortcut exists for this particular starred-button does not invalidate this answer.Acculturate
While this maybe an old post, would like to add that Android studio also uses the android:button="@android:drawable/btn_star" methodNapoleonnapoleonic
How to give width and height to the bitmap in the selector once you specify android:button?Moslem
Note that if you use the button attribute, it will not scale a background image. If you use a background attribute instead, and set android:button=@null, your background will scale to the size of the checkboxAmbrogio
adding bare links is discouraged, please elaborateWhomp
P
45

Copy the btn_check.xml from android-sdk/platforms/android-#/data/res/drawable to your project's drawable folder and change the 'on' and 'off' image states to your custom images.

Then your xml will just need android:button="@drawable/btn_check"

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

If you want to use different default android icons, you can use android:button="@android:drawable/..."

Peace answered 1/8, 2012 at 20:14 Comment(3)
Bad advice. Icons may be changed from version to version and may disappear at all. If you really like the default icon, you can grab it from sources.Transient
Are you saying referencing the default icons directly via "@android:drawable/..." is a bad idea, or this process entirely?Peace
Example: reference to holo icons will crash your app on pre-honeycomb devices. It is really difficult to maintain and debug such troubles. So I usually copy not only xml but the images too to be hundreed percent sure the resources will be found. Also this is very important to ensure UI look the same on every device.Transient
R
28

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" />
Redundancy answered 28/6, 2018 at 7:36 Comment(1)
Some explanation would help new users understand how your code solves the issue.Quasijudicial
A
6

If you have Android open source code, you can find the styles definition under:
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>
Aldercy answered 18/10, 2012 at 8:43 Comment(0)
V
5

Based on the Enselic and Rahul answers.

It works for me (before and after 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" />
Vietcong answered 5/5, 2020 at 22:58 Comment(0)
E
3

Try it -

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

Add this attrib -

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

Use like -

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

It will fix all your porblems.

Edom answered 21/7, 2015 at 9:26 Comment(1)
It's missing the onSaveInstanceState() and onRestoreInstanceState() methods, I think the checked state would be lost on rotationGalatea
T
2

Another option is to use a ToggleButton with null background and a custom button.

Bellow an example that includes a selector to the text color as well.

<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>
Tropic answered 6/10, 2015 at 8:19 Comment(0)
H
2

If you are using custom adapters than android:focusable="false" and android:focusableInTouchMode="false" are nessesury to make list items clickable while using checkbox.

<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>
Harken answered 11/6, 2018 at 7:49 Comment(0)
H
2

If you use androidx.appcompat:appcompat and want a custom drawable (of type selector with android:state_checked) to work on old platform versions in addition to new platform versions, you need to use

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

instead of

    <CheckBox
        android:button="@drawable/..."
Histolysis answered 6/2, 2020 at 13:9 Comment(0)
O
0

Adding custom drawable in the android:button did not work for me in Material Checkbox version-1.3.0 . I had to set android:drawable="@drawable/checkbox_selector" instead and also set android:button="@null" . You can also add android:drawablePadding to make it look good. However, this makes the entire checkbox clickable (along with the text).

Orthogenetic answered 21/5, 2021 at 6:1 Comment(0)
T
0

All you need two drawable one for checked state and other for unchecked or default state. You can then create a background drawable selector(xml) and apply it as background to your checkbox. As mentioned below

<?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/ic_checkbox_checked_24" />
    <item
        android:state_checked="false"
        android:drawable="@drawable/ic_checkbox_unchecked_24" />
    <item
        android:drawable="@drawable/ic_checkbox_unchecked_24"/>
</selector>

No your checkbox in xml should look like this.

<CheckBox
      android:id="@+id/check_box"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:button="@null"
      android:background="@drawable/checkbox_background_drawable"/>

Make sure you have maked the button attribute of checkbox to null.

Tricyclic answered 26/4, 2023 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.