package com.circlegate.liban.view;
import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.CheckBox;
import android.widget.Checkable;
import android.widget.ImageButton;
public class CheckableImageButton extends ImageButton implements Checkable {
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
private boolean mChecked;
private boolean mBroadcasting;
private OnCheckedChangeListener mOnCheckedChangeListener;
public CheckableImageButton(Context context) {
this(context, null);
}
public CheckableImageButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CheckableImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
//
// GETTERS
//
@Override
public boolean isChecked() {
return mChecked;
}
//
// SETTERS
//
@Override
public void setChecked(boolean checked) {
if (this.mChecked != checked) {
mChecked = checked;
refreshDrawableState();
// Avoid infinite recursions if setChecked() is called from a listener
if (mBroadcasting) {
return;
}
mBroadcasting = true;
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
mBroadcasting = false;
}
}
@Override
public void toggle() {
setChecked(!mChecked);
}
@Override
public boolean performClick() {
toggle();
return super.performClick();
}
//
// CALLBACKS
//
/**
* Register a callback to be invoked when the checked state of this button changes.
*
* @param listener
* the callback to call on checked state change
*/
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
mOnCheckedChangeListener = listener;
}
/**
* Interface definition for a callback.
*/
public static interface OnCheckedChangeListener {
/**
* Called when the checked state of a button has changed.
*
* @param button
* The button view whose state has changed.
* @param isChecked
* The new checked state of button.
*/
void onCheckedChanged(CheckableImageButton button, boolean isChecked);
}
@Override
public int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
invalidate();
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setChecked(isChecked());
event.setClassName(CheckBox.class.getName());
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
info.setCheckable(true);
info.setChecked(isChecked());
info.setClassName(CheckBox.class.getName());
}
}
//
// SAVED STATE
//
public static class SavedState extends BaseSavedState {
boolean checked;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
checked = (Boolean) in.readValue(null);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeValue(checked);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.checked = isChecked();
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setChecked(ss.checked);
requestLayout();
}
}