studio linearlayout example custom create control android resources attributes themes drawable

linearlayout - Acceso a recursos definidos en theme y attrs.xml android



draw view android (5)

Tengo un escenario en el que quiero establecer un Drawable dependiendo del tema definido.

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

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

Entonces, como habrán notado, estoy definiendo un Attr homeIcon personalizado y estableciendo el valor del atributo en AppTheme.

Cuando defino este atributo en un diseño XML e intento acceder a él, 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 el Drawable ic_home en un ImageView .

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

Intenté hacer esto con una LayerList Drawable , al definir un titular LayerList Drawable , que da como resultado una excepción de recurso no encontrado:

<?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 al Drawable definido en un Theme definido personalizado mediante programación.


Aquí están 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 encontré cómo conseguirlos es la siguiente.

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

Al utilizar R.styleable.AppTheme_homeIcon nos R.styleable.AppTheme_homeIcon exactamente a ese atributo que queremos. Por ejemplo, si tenemos tendríamos algunos atributos más de los que podemos referenciarlos 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 están definidos, obtendrá valores predeterminados y sin excepciones.


Creo que puedes obtener el Drawable 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();


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

no hay necesidad de reciclar nada aquí ...

uso:

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



Utilicé el siguiente método para obtener el atributo de estilo de formulario ID de recurso. 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 :-)