StateImageButton.java
Overview
`StateImageButton` is a custom Android UI component extending the standard `ImageButton`. It provides a toggleable button that visually reflects two distinct states — *checked* and *not checked* — by switching its background drawable accordingly. This component is primarily designed for use cases where a binary state toggle is needed with an intuitive visual cue, such as toggling subtitles, mute/unmute, or similar features.
The class supports XML attribute customization for specifying the drawable resources representing the checked and unchecked states. It also integrates with Android Data Binding, enabling seamless state updates directly from layout XML files.
Class Details
public class StateImageButton extends ImageButton
A toggleable image button that switches its background resource based on an internal boolean checked state.
Inner Interface
public interface OnAction
Purpose: Defines a callback interface with a single method
onAction()to notify listeners about an action event.Usage: While declared, it is not utilized inside this class but can be implemented externally to handle button actions.
Fields
Field Name | Type | Description |
|---|---|---|
`private boolean isChecked` | boolean | Stores the current checked state of the button. |
int | Drawable resource ID used when button is checked. | |
int | Drawable resource ID used when button is unchecked. |
Constructors
public StateImageButton(Context context)
public StateImageButton(Context context, AttributeSet attrs)
public StateImageButton(Context context, AttributeSet attrs, int defStyleAttr)
Description: Standard constructors for custom views.
Parameters:
context: The Context the view is running in.attrs: AttributeSet containing XML attributes.defStyleAttr: Default style attribute.
Behavior: All constructors call a private
init(attrs)method to initialize drawables and apply any custom XML attributes.
Methods
private void init(@Nullable AttributeSet attrs)
Purpose: Initializes drawable resource IDs for the checked and unchecked states, applying custom attributes if present.
Parameters:
attrs: XML attributes, nullable.
Behavior:
Defaults are set to
R.drawable.tubi_tv_subtitles_onandR.drawable.tubi_tv_subtitles_off.If attributes are provided, it attempts to override these defaults with the values from the
StateImageButtonstyleable attributes:state_checkedstate_not_checked
Calls
setDrawableSelector()to apply the correct drawable based on initial state.
private void toggleCheckState()
Purpose: Toggles the internal
isCheckedboolean and updates the button's drawable accordingly.Usage: Typically called when the button is clicked (though this class does not implement click handling internally).
private void setDrawableSelector()
Purpose: Sets the background drawable resource depending on the current checked state.
Behavior:
If
isCheckedis true, usesmStateCheckedDrawableId.Otherwise, uses
mStateNotCheckedDrawableId.Calls
invalidate()to refresh the view.
public boolean isChecked()
Returns:
boolean— current checked state.Usage: To query whether the button is currently checked.
public void setChecked(boolean checked)
Parameters:
checked: The desired checked state.
Behavior: Sets the internal state and updates the drawable.
Usage: Can be used programmatically to set the button state.
public static void onStateChanged(StateImageButton imageButton, boolean checked)
Annotation:
@BindingAdapter("bind:setCheckedState")Purpose: Enables data binding support for setting the checked state from XML layouts.
Parameters:
imageButton: The instance ofStateImageButtonto update.checked: The boolean value for the checked state.
Usage:
<com.tubitv.media.views.StateImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
bind:setCheckedState="@{viewModel.isSubtitleEnabled}" />
Implementation Details
State Management: The class internally manages the checked state through a boolean
isChecked.Drawable Management: Two drawable resource IDs represent the two states; these can be set via XML attributes or default to predefined resources.
Data Binding Integration: The static
onStateChangedmethod allows the button's state to be updated reactively via Android Data Binding.View Refresh: Calling
setBackgroundResource()andinvalidate()ensures the UI updates to reflect the current state immediately.No Click Handling Internally: This class does not implement click listeners or toggle state on click by itself, leaving that responsibility to the containing activity or fragment.
Interaction with Other System Components
XML Attribute Configuration: The class reads custom attributes (
state_checkedandstate_not_checked) from theR.styleable.StateImageButton. These need to be defined in the app'sattrs.xml.Resource Dependencies: Uses drawable resources from
R.drawablerepresenting checked and unchecked states.Data Binding: Works with Android's Data Binding framework via the
@BindingAdapterannotation.Parent UI Components: Typically used inside layouts that require toggleable image buttons, for example, media control bars.
Usage Example
// In an Activity or Fragment
StateImageButton subtitleToggle = findViewById(R.id.subtitleToggle);
subtitleToggle.setChecked(true);
// Or toggle state manually
subtitleToggle.setChecked(!subtitleToggle.isChecked());
**With XML attributes:**
<com.tubitv.media.views.StateImageButton
android:id="@+id/subtitleToggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:state_checked="@drawable/custom_checked_icon"
app:state_not_checked="@drawable/custom_unchecked_icon" />
Visual Diagram
classDiagram
class StateImageButton {
-boolean isChecked
-int mStateCheckedDrawableId
-int mStateNotCheckedDrawableId
+StateImageButton(Context)
+StateImageButton(Context, AttributeSet)
+StateImageButton(Context, AttributeSet, int)
+boolean isChecked()
+void setChecked(boolean)
-void init(AttributeSet)
-void toggleCheckState()
-void setDrawableSelector()
+static void onStateChanged(StateImageButton, boolean)
}
class OnAction {
<<interface>>
+void onAction()
}
StateImageButton ..> OnAction : "defines"
Summary
`StateImageButton` is a lightweight, customizable toggle button tailored for Android applications requiring visual state changes between two modes. It is flexible due to its support for custom drawables, integration with data binding, and simple API for state control. This component encapsulates state logic and drawable management cleanly while leaving interaction handling to the parent view or controller.