Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access resource defined in theme and attrs.xml android

I have a scenario in which I want to set a Drawable depending upon the theme defined.

To explain this further, Here is what I have in code:

\res\values\attrs.xml

<resources>     <declare-styleable name="AppTheme">         <attr name="homeIcon" format="reference" />     </declare-styleable> </resources> 

res\values\styles.xml

<resources>     <style name="AppTheme" parent="android:style/Theme">         <item name="attr/homeIcon">@drawable/ic_home</item>     </style> </resources> 

AndroidManifest.xml

    <application android:label="@string/app_name"         android:theme="@style/AppTheme">         <activity android:name=".MainActivity" android:label="@string/app_name">             <intent-filter>                 <action android:name="android.intent.action.MAIN" />                 <category android:name="android.intent.category.LAUNCHER" />             </intent-filter>         </activity>     </application> 

So as you have noticed I am defining a custom attr homeIcon and setting the attribute value in AppTheme.

When I define this attribute in a layout XML and try to access it it works smoothly

<ImageView android:id="@+id/img"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:src="?attr/homeIcon" /> 

and renders the Drawable ic_home in an ImageView.

But I am not able to figure out how to access the Drawable programmatically.

I tried to do this with a work around, by defining a holder LayerList Drawable, which results in resource not found exception:

<?xml version="1.0" encoding="utf-8"?> <layer-list     xmlns:android="http://schemas.android.com/apk/res/android" >     <item         android:drawable="?attr/homeIcon" /> </layer-list> 

Summary I want to access the Drawable defined in a custom defined Theme programmatically.

like image 462
Shardul Avatar asked Jan 09 '12 18:01

Shardul


People also ask

What is Attrs XML in Android?

An <attr> element has two xml attributes name and format . name lets you call it something and this is how you end up referring to it in code, e.g., R. attr. my_attribute . The format attribute can have different values depending on the 'type' of attribute you want.

What are the resources how different types of resources managed in Android explain?

Resources are the additional files and static content that your code uses, such as bitmaps, layout definitions, user interface strings, animation instructions, and more. You should always externalize app resources such as images and strings from your code, so that you can maintain them independently.

What is resource folder in Android?

The res/values folder is used to store the values for the resources that are used in many Android projects to include features of color, styles, dimensions etc.

What is the use of resource ID in Android?

drawable for all drawable resources) and for each resource of that type, there is a static integer (for example, R. drawable. icon ). This integer is the resource ID that you can use to retrieve your resource.


2 Answers

I think you can get the Drawable with this code:

TypedArray a = getTheme().obtainStyledAttributes(R.style.AppTheme, new int[] {R.attr.homeIcon});      int attributeResourceId = a.getResourceId(0, 0); Drawable drawable = getResources().getDrawable(attributeResourceId); a.recycle(); 
like image 75
dmaxi Avatar answered Oct 18 '22 17:10

dmaxi


Another possible way to do it:

public static int getResIdFromAttribute(final Activity activity,final int attr) {     if(attr==0)         return 0;     final TypedValue typedvalueattr=new TypedValue();     activity.getTheme().resolveAttribute(attr,typedvalueattr,true);     return typedvalueattr.resourceId; } 

Or in Kotlin:

@JvmStatic fun getResIdFromAttribute(activity: Activity, attr: Int): Int {     if (attr == 0)         return 0     val typedValue = TypedValue()     activity.theme.resolveAttribute(attr, typedValue, true)     return typedValue.resourceId } 

no need to recycle anything here...

usage:

int drawableResId=getResIdFromAttribute(this,R.attr.homeIcon); Drawable drawable = getResources().getDrawable(drawableResId); 
like image 21
android developer Avatar answered Oct 18 '22 17:10

android developer