Skip to content

Instantly share code, notes, and snippets.

@Arutyun2312
Last active September 26, 2020 12:19
Show Gist options
  • Save Arutyun2312/0553cf6e11e6dc5dd54e8fc1a9143901 to your computer and use it in GitHub Desktop.
Save Arutyun2312/0553cf6e11e6dc5dd54e8fc1a9143901 to your computer and use it in GitHub Desktop.
ImageButton that is checkable. Supports the state_checked, so that selectors can work seamlessly. MUST put the file attrs.xml in raw/values. Min sdk is 16
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CheckableImageButton">
<attr name="android:checked" format="boolean" />
</declare-styleable>
</resources>
/*
Do whatever u want, I don't care
Arutyun 2020
*/
import android.*
import android.content.*
import android.content.res.*
import android.os.*
import android.util.*
import android.view.*
import android.view.accessibility.*
import android.widget.*
import androidx.appcompat.widget.*
import androidx.core.view.*
import androidx.core.view.accessibility.*
class CheckableImageButton(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : AppCompatImageButton(context, attrs, defStyleAttr), Checkable
{
private var mChecked = false
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, androidx.appcompat.R.attr.imageButtonStyle)
override fun isChecked() = mChecked
override fun setChecked(checked: Boolean)
{
if (mChecked != checked)
{
mChecked = checked
refreshDrawableState()
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)
}
}
override fun toggle()
{
isChecked = !mChecked
}
override fun performClick(): Boolean
{
toggle()
return super.performClick()
}
override fun onCreateDrawableState(extraSpace: Int): IntArray = if (mChecked)
mergeDrawableStates(super.onCreateDrawableState(extraSpace + 1), intArrayOf(android.R.attr.state_checked))
else
super.onCreateDrawableState(extraSpace)
override fun onSaveInstanceState() = SavedState(super.onSaveInstanceState()).apply { checked = mChecked }
override fun onRestoreInstanceState(state: Parcelable)
{
if (state !is SavedState)
super.onRestoreInstanceState(state)
else
{
super.onRestoreInstanceState(state.superState)
isChecked = state.checked
}
}
class SavedState : BaseSavedState
{
var checked = false
internal constructor(superState: Parcelable?) : super(superState)
private constructor(`in`: Parcel) : super(`in`)
{
checked = `in`.readInt() == 1
}
override fun writeToParcel(out: Parcel, flags: Int)
{
super.writeToParcel(out, flags)
out.writeInt(if (checked) 1 else 0)
}
}
init
{
val a = context.obtainStyledAttributes(attrs, R.styleable.CheckableImageButton)
isChecked = a.getBoolean(R.styleable.CheckableImageButton_android_checked, false)
a.recycle()
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat()
{
override fun onInitializeAccessibilityEvent(host: View?, event: AccessibilityEvent)
{
super.onInitializeAccessibilityEvent(host, event)
event.isChecked = isChecked
}
override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfoCompat)
{
super.onInitializeAccessibilityNodeInfo(host, info)
info.isCheckable = true
info.isChecked = isChecked
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment