73

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"...

3 Answers 3

168

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

Sign up to request clarification or add additional context in comments.

7 Comments

looking at this again, it could be added that a faulty namespace declaration will not give compile time errors. In this example, it could look like xmlns:myapp="http://schemas.android.com/apk/res/se.jog.mob" if class MyLayout is declared in se.jog.mob.
You should call a.recycle() when you are done using the styled attributes.
In gradle projects, custom schema should always be "schemas.android.com/apk/res-auto"
Yes, there is a question about the deprecation here: stackoverflow.com/questions/11947603/…
Using integer didn't let me select from @drawable in the XML. I had tu use fromat="reference" and then it worked.
|
52

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.

2 Comments

Custom backgroundImage attribute setting in your example is wrong. More like: custom:backgroundImage="@drawable/myImage"
This is the best answer. When you use format="reference", you will see the dropdown list to choise resource at custom:backgroundImage="@drawable/myImage"
21

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.

1 Comment

Found the above helpful (<attr name="src" format="reference|color" />), Upvote.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.