2012-01-09 11 views
33

Tengo un escenario en el que quiero establecer un Drawable según el tema definido.Recurso de acceso definido en theme y attrs.xml android

Para explicar esto más, aquí es lo que tengo en el código:

\ res \ valores \ attrs.xml

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

res \ valores \ 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> 

Como ya habrás notado, estoy definiendo un attr homeIcon personalizado y estableciendo el valor del atributo en AppTheme.

Cuando defino este atributo XML en un diseño y tratar de acceder a él es que funciona sin problemas

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

y hace que la ic_home Drawable en un ImageView.

Pero no puedo averiguar cómo acceder al Drawable mediante programación.

he tratado de hacer esto con un trabajo alrededor, mediante la definición de un soporte LayerList Drawable, que se traduce en recursos que no se encuentra una excepción:

<?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> 

Resumen quiero acceder a la Drawable definido en una personalizado definido Theme programmatically.

Respuesta

64

creo que se puede conseguir el Disponibles con este código:

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(); 
+0

Califíquelo si le conviene. – dmaxi

+0

Gracias :) ¡funcionó! – Shardul

+0

¡Trabajó para mí para ...! ¡Gracias! :) – DroidBee

9

Otra posible forma de hacerlo:

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; 
    } 

sin necesidad de reciclar cualquier cosa aquí ...

uso:

int drawableResId=getResIdFromAttribute(this,R.attr.homeIcon); 
Drawable drawable = getResources().getDrawable(drawableResId); 
+0

funcionó para mí. , pero ¿por qué no hay necesidad de reciclar? –

+1

@OlumideOyetoke Consulte los documentos: http://developer.android.com/reference/android/util/TypedValue.html. No hay función de reciclaje allí ... –

2

que se utiliza por debajo método para obtener la forma de identificación de recursos atributo de estilo. Luego se puede usar para dibujar, cadena, dimensión, etc.

TypedArray typedArray = context.getTheme().obtainStyledAttributes(new int[] { R.attr.attrName }); 
int resourceId = typedArray.getResourceId(0, defaultResourceId); 
typedArray.recycle(); 

aplausos :-)

0

He aquí los resultados de mi investigación, con respecto a este tema. Si tenemos declare-stylable entonces podemos anular esos valores en los temas.

Hasta ahora, la mejor forma en que he encontrado cómo conseguirlos es el siguiente.

TypedArray a = context.getTheme().obtainStyledAttributes(R.styleable.AppTheme); 
a.getDrawable(R.styleable.AppTheme_homeIcon); 

Mediante el uso de R.styleable.AppTheme_homeIcon que hacen referencia exactamente ese atributo que queremos. Por ejemplo, si tenemos que tener pocos atributos más de lo que podemos hacer referencia a ellos de la siguiente manera:

a.getColor(R.styleable.AppTheme_color,defaultValue); 
a.getDimension(R.styleable.AppTheme_width,defaultWidth); 

Y si en el tema actual esos atributos no estaban definidas que obtendremos valores por defecto y no hay excepciones.

Cuestiones relacionadas