androidandroid-styles

Custom styled attribute always set by default


I have defined custom styled attribute for color..

<declare-styleable name="CustomView">
        <attr name="custom1" format="boolean" />
        <attr name="custom2" format="reference|color" />
</declare-styleable>

When fetching attributes defined in xml through obtainStyledAttributes, it always returns size as 1, even if no attributes are defined in xml.

TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CustomView, 0, 0);
final int size = attributes.getIndexCount();

for(int i = 0; i < size; i++) {
    final int attr = attributes.getIndex(i);
    if (attr == R.styleable.CustomView_custom1) {
        boolean b = attributes.getBoolean(attr, false);
     }
    else if (attr == R.styleable.CustomView_custom2) {
        ColorStateList cs = attributes.getColorStateList(attr);
        int color = cs.getDefaultColor();
    }
}

Here size is always 1 even if no attribute defined in xml.. Because of that color gets some random value, not sure from where it is getting some value?

Output is as below:

Test﹕ ----
Test﹕ CustomView= 2130772048
Test﹕ CustomView= 2130772049
Test﹕ ----
Test﹕ AttributeSet= 16842901 textSize
Test﹕ AttributeSet= 16842904 textColor
Test﹕ AttributeSet= 16842927 gravity
Test﹕ AttributeSet= 16842960 id
Test﹕ AttributeSet= 16842966 paddingLeft
Test﹕ AttributeSet= 16842968 paddingRight
Test﹕ AttributeSet= 16842996 layout_width
Test﹕ AttributeSet= 16842997 layout_height
Test﹕ AttributeSet= 16843000 layout_marginTop
Test﹕ AttributeSet= 16843101 singleLine
Test﹕ AttributeSet= 16843119 drawableLeft
Test﹕ AttributeSet= 16843121 drawablePadding
Test﹕ AttributeSet= 16843139 layout_toRightOf
Test﹕ AttributeSet= 2130772048 custom1

Solution

  • Strange problem. I can only suggest that you add debug log output and experiment with changes to get more visibility on what is going on.

    These statements dump the attribute ids for your custom view and in the AttributeSet for the instance of your custom view in the layout XML.

    Log.i("Test", "----");
    for (int id : R.styleable.CustomView) {
        Log.i("Test", "CustomView= " + id);
    }
    
    Log.i("Test", "----");
    int n = attrs.getAttributeCount();
    for (int i = 0; i < n; i++) {
        Log.i("Test", "AttributeSet= " + attrs.getAttributeNameResource(i) + " " + attrs.getAttributeName(i));
    }
    

    To see if the custom2 attribute is set in the theme or not:

    TypedValue val = new TypedValue();
    boolean resolved = context.getTheme().resolveAttribute(R.attr.custom2, val, true);
    if (resolved) {
        Log.i("Test", "Custom2 in theme");
    } else {
        Log.i("Test", "Custom2 NOT in theme");
    }