Custom attr get color returns invalid values
If you want every types of color to work
- hex:
#ff0000
- color resource:
@color/primary
- color selector:
@color/primaryWithStates
You need to define your property as both color and reference
<attr name="propertyTextColor" format="color|reference" />
Then you simply access the value using getColorStateList
val colors = attr.getColorStateList(R.styleable.PropertyView_propertyTextColor)
titleTextView.setTextColor(colors)
For advanced needs where you want to digest the ColorStateList
yourself
- In the first 2 cases you can access the color using
colors.defaultColor
- If you used a selector you have to call the method
getColorForState
So, the easiest way to extract the color is by doing
val currentColor = colors.getColorForState(drawableState, colors.defaultColor)
// do whatever you want with the color
It returns the color if there is one for the current state, otherwise the default one
Attention: getColorForState
should be placed in the drawableStateChanged()
method to be notified every time the state changes
The is some sort of bug with attrs
.
The following works perfectly.
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Your View -->
<declare-styleable name="YourView">
<attr name="tint_color" format="reference" /> <!-- Important -->
<attr name="ripple_drawable" format="reference" /> <!-- Important -->
</declare-styleable>
</resources>
YourView.java
public YourView(Context context) {
this(context, null);
}
public YourView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public YourView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// Get attrs
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.YourView, defStyleAttr, 0);
// Set tint
int tintStyle = R.styleable.YourView_tint_color;
if (a.hasValue(tintStyle)) {
mTintColor = a.getResourceId(tintStyle, 0); // Important
setTint(mTintColor);
}
// Set Ripple
int rippleStyle = R.styleable.YourView_ripple_drawable;
if (a.hasValue(rippleStyle)) {
mRippleDrawable = a.getResourceId(rippleStyle, 0); // Important
setRipple(mRippleDrawable);
}
// End
a.recycle();
}
Usage
<com.your.app.YourView
...
app:ripple_drawable="@drawable/ripple_default"
app:tint_color="@color/colorWhite" />
You are using a reference to a color in your example, however according to your attrs.xml file, that property must be of a color type, not a reference. This is probably the reason why when you used a hex color code it worked, but using a reference returned -1.
If you do change the format to a reference, you should also change the method to retrieve it from a.getColor()
to a.getColorStateList()
.