Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom CheckBox image gets cut off

CheckBox

As you can see in the image above. There are three views on this screenshot.
- The first item is CheckBox with text and having state off.
- The second item is CheckBox without text and having state on.
- The last item is ImageView with src pointing to the drawable image.

The CheckBoxes were customized using android:button.

small checkbox

As I tried using smaller images, all of the checkbox is left-aligned.

Comparing these two images tell me that the default size of the CheckBox seems fixed to certain size until text attribute is large enough to require extending.

There is nothing special in the file as well. See following.

custom_cb.xml

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

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

</selector>

layout.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <CheckBox android:id="@+id/cbFalse"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:button="@drawable/custom_cb"
              android:text="" />
    <CheckBox android:id="@+id/cbTrue"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:button="@drawable/custom_cb"
              android:focusable="false"
              android:checked="true"
              android:layout_toRightOf="@id/cbFalse" />
    <ImageView android:id="@+id/imvTrue"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:src="@drawable/creditcard"
              android:layout_toRightOf="@id/cbTrue" />
</RelativeLayout>

Is there anyway I can use bigger image for CheckBox while keeping the size as wrap_content? If I set CheckBox layout_width to actual pixel or dp then it display full image but that mean I have to manually check for the size every time it change.

like image 325
RobGThai Avatar asked Apr 18 '13 11:04

RobGThai


4 Answers

Today I had the same problem (my custom image was cutted on the left side). I fixed it putting:

android:button="@null"
android:background="@drawable/my_custom_checkbox_state.xml"
like image 121
Luca Sepe Avatar answered Nov 20 '22 02:11

Luca Sepe


Just use

android:button="@null"
android:background="@null"
android:drawableLeft="your custom selector"
android:drawablePadding="as you need"
android:text="your text"

Thats it.. Its working fine..

like image 37
Sripathi Avatar answered Nov 20 '22 03:11

Sripathi


You only have to change your drawable from android:button to android:drawableLeft or android:drawableRight. And set the button to null to not show the default checkbox.

My checkbox looks like this:

<CheckBox
   android:id="@+id/cb_toggle_switch"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:button="@null"
   android:drawableLeft="@drawable/livescore_btn_check" />
like image 21
swordfish Avatar answered Nov 20 '22 03:11

swordfish


CheckBox drawables did not work for me at all, android:button and android:background gave completely erratic results and nothing could fix it.

So I wrote my own "custom checkbox".

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import org.apache.commons.lang3.StringUtils;

import butterknife.Bind;
import butterknife.ButterKnife;
import com.example.myapp.R;

/**
 * Created by Zhuinden on 2015.12.02..
 */
public class CustomCheckbox
        extends LinearLayout
        implements View.OnClickListener {
    public CustomCheckbox(Context context) {
        super(context);
        init(null, -1);
    }

    public CustomCheckbox(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, -1);
    }

    @TargetApi(11)
    public CustomCheckbox(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs, defStyleAttr);
    }

    @TargetApi(21)
    public CustomCheckbox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs, defStyleAttr);
    }

    private void init(AttributeSet attributeSet, int defStyle) {
        TypedArray a = null;
        if(defStyle != -1) {
            a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CustomCheckbox, defStyle, 0);
        } else {
            a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CustomCheckbox);
        }
        defImageRes = a.getResourceId(0, 0);
        checkedImageRes = a.getResourceId(1, 0);
        checked = a.getBoolean(2, false);
        typeface = a.getString(3);
        if(StringUtils.isEmpty(typeface)) {
            typeface = "Oswald-Book.otf";
        }
        text = a.getString(4);
        inactiveTextcolor = a.getInteger(5, android.R.color.black);
        activeTextcolor = a.getInteger(6, android.R.color.red);
        textsize = a.getDimensionPixelSize(7, 0);
        a.recycle();
        setOnClickListener(this);
        if(!isInEditMode()) {
            LayoutInflater.from(getContext()).inflate(R.layout.view_custom_checkbox, this, true);
            ButterKnife.bind(this);
            imageView.setImageResource(checked ? checkedImageRes : defImageRes);
            typefaceTextView.setTypeface(typeface);
            if(!StringUtils.isEmpty(text)) {
                typefaceTextView.setText(text);
            }
            if(textsize != 0) {
                typefaceTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textsize);
            } else {
                typefaceTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
            }
        }
    }

    boolean checked;
    int defImageRes;
    int checkedImageRes;
    String typeface;
    String text;
    int inactiveTextcolor;
    int activeTextcolor;
    int textsize;

    OnCheckedChangeListener onCheckedChangeListener;

    @Bind(R.id.custom_checkbox_imageview)
    ImageView imageView;

    @Bind(R.id.custom_checkbox_text)
    TypefaceTextView typefaceTextView;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

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

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

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

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
        imageView.setImageResource(checked ? checkedImageRes : defImageRes);
        typefaceTextView.setTextColor(checked ? activeTextcolor : inactiveTextcolor);
    }

    public void setTextColor(int color) {
        typefaceTextView.setTextColor(color);
    }



    @Override
    public Parcelable onSaveInstanceState() {
        //begin boilerplate code that allows parent classes to save state
        Parcelable superState = super.onSaveInstanceState();

        SavedState ss = new SavedState(superState);
        //end

        ss.checked = this.checked;
        ss.defImageRes = this.defImageRes;
        ss.checkedImageRes = this.checkedImageRes;
        ss.typeface = this.typeface;
        ss.text = this.text;
        ss.inactiveTextcolor = this.inactiveTextcolor;
        ss.activeTextcolor = this.activeTextcolor;
        ss.textsize = this.textsize;

        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        //begin boilerplate code so parent classes can restore state
        if(!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }

        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        //end

        this.checked = ss.checked;
        this.defImageRes = ss.defImageRes;
        this.checkedImageRes = ss.checkedImageRes;
        this.typeface = ss.typeface;
        this.text = ss.text;
        this.inactiveTextcolor = ss.inactiveTextcolor;
        this.activeTextcolor = ss.activeTextcolor;
        this.textsize = ss.textsize;
    }

    static class SavedState
            extends BaseSavedState {
        boolean checked;
        int defImageRes;
        int checkedImageRes;
        String typeface;
        String text;
        int inactiveTextcolor;
        int activeTextcolor;
        int textsize;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            this.checked = in.readByte() > 0;
            this.defImageRes = in.readInt();
            this.checkedImageRes = in.readInt();
            this.typeface = in.readString();
            this.text = in.readString();
            this.inactiveTextcolor = in.readInt();
            this.activeTextcolor = in.readInt();
            this.textsize = in.readInt();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeByte(this.checked ? (byte) 0x01 : (byte) 0x00);
            out.writeInt(this.defImageRes);
            out.writeInt(this.checkedImageRes);
            out.writeString(this.typeface);
            out.writeString(this.text);
            out.writeInt(this.inactiveTextcolor);
            out.writeInt(this.activeTextcolor);
            out.writeInt(this.textsize);
        }

        //required field that makes Parcelables from a Parcel
        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}

Using the following attrs.xml

<resources
    <declare-styleable name="CustomCheckbox">
        <attr name="default_img" format="integer"/>
        <attr name="checked_img" format="integer"/>
        <attr name="checked" format="boolean"/>
        <attr name="chx_typeface" format="string"/>
        <attr name="text" format="string"/>
        <attr name="inactive_textcolor" format="integer"/>
        <attr name="active_textcolor" format="integer"/>
        <attr name="textsize" format="dimension"/>
    </declare-styleable>
</resources>

With following view_custom_checkbox.xml layout:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/custom_checkbox_imageview"
        android:layout_width="@dimen/_15sdp"
        android:layout_height="@dimen/_15sdp"
        />

    <com.example.TypefaceTextView
        android:id="@+id/custom_checkbox_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</merge>

And example:

                        <com.example.CustomCheckbox
                            android:id="@+id/program_info_record_button"
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:layout_centerHorizontal="true"
                            android:clickable="true"
                            android:gravity="center"
                            app:default_img="@drawable/ic_recording_off"
                            app:checked_img="@drawable/ic_recording_on"
                            app:text="@string/record"
                            app:inactive_textcolor="@color/program_info_buttons_inactive"
                            app:active_textcolor="@color/active_color"
                            app:textsize="@dimen/programInfoButtonTextSize"
                            app:chx_typeface="SomeTypeface.otf"/>

Modify where necessary.

like image 2
EpicPandaForce Avatar answered Nov 20 '22 03:11

EpicPandaForce