Format attribute value "android:drawable" not valid

Android

Android Problem Overview


I'm trying to create custom attributes to my button but I dont know which format I must use to images in attributes declaration...

<?xml version="1.0" encoding="utf-8"?>
<resources>

	<declare-styleable name="TCButton">
		<attr name="Text" format="string"/>
		<attr name="BackgroundImage" format="android:drawable"	/>
	</declare-styleable>
	

</resources>

Error is in the format="android:drawable"...

Android Solutions


Solution 1 - Android

You can use format="integer", the resource id of the drawable, and AttributeSet.getDrawable(...).

Here is an example.

Declare the attribute as integer in res/values/attrs.xml:

<resources>
    <declare-styleable name="MyLayout">
        <attr name="icon" format="integer" />
    </declare-styleable>
</resources>

Set the attribute to a drawable id in your layout:

<se.jog.MyLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    myapp:icon="@drawable/myImage"
/>

Get the drawable from the attribute in your custom widget component class:

ImageView myIcon;
//...
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyLayout);
Drawable drawable = a.getDrawable(R.styleable.MyLayout_icon);
if (drawable != null)
    myIcon.setBackgroundDrawable(drawable);

To see all options possible check the android src here

Solution 2 - Android

I think it will be better to use it as a simple reference:

<declare-styleable name="TCButton">
        <attr name="customText" format="string"/>
        <attr name="backgroundImage" format="reference"  />
</declare-styleable>

And set it in your xml like this:

<your.package.name.TCButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    custom:customText="Some custom text"
    custom:backgroundImage="@drawable/myImage"
/>

And in your class set the attributes like this:

public TCButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MembershipItemView, 0, 0);

    String customText;
    Drawable backgroundImage;
    try {
        customText = a.getString(R.styleable.TCButton_customText);
        backgroundImage = a.getDrawable(R.styleable.TCButton_backgroundImage);
    } finally {
        a.recycle();
    }

    if(!TextUtils.isEmpty(customText)) {
      ((TextView)findViewById(R.id.yourTextView)).setText(customText);
    }
    
    if(null != backgroundImage) {                    
        ((ImageView)findViewById(R.id.yourImageView)).setBackgroundDrawable(backgroundImage);
    }
}

PS: Don't forget to add this line for the root element of the layout you are using your custom view in

xmlns:custom="http://schemas.android.com/apk/res-auto"

If you don't set this, you won't be able to access your custom attributes.

Solution 3 - Android

From AOSP code, I found how google engineers declare ImageView#src attr.

<declare-styleable name="ImageView">
    <attr name="src" format="reference|color" />
    <attr name="scaleType">
        <enum name="matrix" value="0" />
        <enum name="fitXY" value="1" />
        <enum name="fitStart" value="2" />
        <enum name="fitCenter" value="3" />
        <enum name="fitEnd" value="4" />
        <enum name="center" value="5" />
        <enum name="centerCrop" value="6" />
        <enum name="centerInside" value="7" />
    </attr>
    <attr name="adjustViewBounds" format="boolean" />
    <attr name="maxWidth" format="dimension" />
    <attr name="maxHeight" format="dimension" />
    <attr name="tint" format="color" />
    <attr name="baselineAlignBottom" format="boolean" />
    <attr name="cropToPadding" format="boolean" />
    <attr name="baseline" format="dimension" />
    <attr name="drawableAlpha" format="integer" />
    <attr name="tintMode" />
</declare-styleable>

Above code is a sample and it can cover most case in our development.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTiago CostaView Question on Stackoverflow
Solution 1 - AndroidJOGView Answer on Stackoverflow
Solution 2 - AndroidIonut NegruView Answer on Stackoverflow
Solution 3 - AndroidCoXierView Answer on Stackoverflow