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 unTheme
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);
Si está utilizando una biblioteca de soporte / diseño, la forma más fácil de obtener los objetos extraíbles ahora es:
Context.getDrawable(int)
o
ContextCompat.getDrawable(Context, int)
referencia - https://plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
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 :-)