Reputation: 490
I'm trying to set a custom attribute to my view programmatically, to set a validation state.
First, I created this layout for a text field:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item android:right="1dp" android:left="1dp">
<shape>
<solid android:color="@color/state_color" />
</shape>
</item>
<!-- main color -->
<item
android:bottom="1.5dp"
android:left="2.5dp"
android:right="2.5dp">
<shape>
<solid android:color="@android:color/white" />
</shape>
</item>
<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="5.0dp">
<shape>
<solid android:color="@android:color/white" />
</shape>
</item>
Then defined this attribute:
<attr name="validation_state" format="enum">
<enum name="None" value="0"/>
<enum name="Error" value="1"/>
<enum name="Warning" value="2"/>
<enum name="Success" value="3"/>
</attr>
I also defined these color definitions state_color.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:color="@color/state_error"
app:validation_state="Error"/>
<item
android:color="@color/state_warning"
app:validation_state="Warning"/>
<item
android:color="@color/state_success"
app:validation_state="Success"/>
<item
android:color="@color/state_default"/>
And last I created an own EditText class which extends the one of the Android framework
private static final int[] STATE_MANDATORY = { R.attr.mandatory };
private static final int[] STATE_READONLY = { R.attr.readonly };
private static final int[] STATE_VALIDATION_STATE = { R.attr.validation_state };
private boolean _mandatory = false;
private boolean _readonly = false;
private ValidationState _validationState = ValidationState.NONE;
public mcEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public void setMandatory(final boolean mandatory)
{
_mandatory = mandatory;
refreshDrawableState();
}
@Override
public void setReadOnly(final boolean readonly)
{
_readonly = readonly;
refreshDrawableState();
}
@Override
public void setValidationState(final ValidationState state)
{
_validationState = state;
refreshDrawableState();
}
@Override
protected int[] onCreateDrawableState(int extraSpace)
{
final int[] drawableState = super.onCreateDrawableState(extraSpace + 3);
if (_mandatory)
{
mergeDrawableStates(drawableState, STATE_MANDATORY);
}
if (_readonly)
{
mergeDrawableStates(drawableState, STATE_READONLY);
}
if (_validationState != ValidationState.NONE)
{
mergeDrawableStates(drawableState, STATE_VALIDATION_STATE);
}
return drawableState;
}
I've added this color definition to my view and it also recognises it, so the error state gets shown. But now I don't know how to switch between the different states. I need to set programmatically the attribute "validation_state", but how is that possible?
Upvotes: 3
Views: 2416
Reputation: 1813
It seems that android does not support enum attributes for this kind of work. You must have to work with boolean attributes
<attr name="validation_state_none" format="boolean"/>
<attr name="validation_state_error" format="boolean"/>
...
The most common example of what you trying to do is like focusable, editable attributes. And it's handled with atomic booleans attributes in android source
Another solution that might help you (Not tested) is to create your own drawable programmatically. Take a look at DrawableContainer and StateListDrawable
Upvotes: 1