I have a group of FrameLayout
which I want to be checkable/selectable,
That is, after a click I would like the FrameLayout
to display as checked
- when pressed again I would like it to become unchecked
. What's more, I want this visual que to be described as usual through though the use of a <selector>
.
I can't seem to get this working - I'm not sure what I'm missing:
public class CheckableFrameLayout extends FrameLayout implements Checkable {
private boolean mChecked = false;
public CheckableFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setChecked(boolean checked) {
mChecked = checked;
refreshDrawableState();
}
public boolean isChecked() {
return mChecked;
}
public void toggle() {
setChecked(!mChecked);
}
}
The layout of the CheckableFrameLayout
:
<com.test.view.CheckableFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/selector_horizontal"
android:clickable="true" >
The selector backing it (selector_horizontal.xml):
<item android:drawable="@drawable/selector_vertical_selected" android:state_pressed="false" android:state_checked="true"/>
<item android:drawable="@drawable/selector_vertical_pressed" android:state_pressed="true" android:state_checked="false"/>
<item android:drawable="@drawable/selector_vertical_normal" android:state_pressed="false" android:state_checked="false"/>
Using the above code the "state_pressed" is working fine, but the View itself is not becoming checked (not is the Checkable
code being called as discovered through debug).
Here's a complete working example for a CheckableButton. It also works on Android 4.2.
Adding the following code to a
Checkable
class allows Selectors to work:In addition to Graeme's answer above do the following modification to toggle()
Try using
android:state_activated
.From the docs:
Graeme's solution doesn't worked from me under Android 4.0.3 (and I suppose it won't work under 4.0 too). Instead you can change
state_checked
tostate_activated
:and use
setActivated
inside yoursetChecked
:and that is all. Implementing
onCreateDrawableState
isn't required here.Try reordering tags in your
selector_horizontal.xml
These are evaluated top to bottom. It seems that in your case eitherandroid:state_pressed="false" or android:state_pressed="true"
is applied and evaluation never reaches third line withandroid:state_checked="true"
Try moving first line to last: