J'ai un scénario dans lequel je veux définir une Drawable
en fonction du thème défini.
Pour expliquer cela davantage, voici ce que j'ai dans le 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>
Comme vous l'avez constaté, je définis un attr homeIcon personnalisé et la valeur de l'attribut dans AppTheme.
Lorsque je définis cet attribut dans un XML de mise en page et que je tente d'y accéder, tout se passe bien.
<ImageView Android:id="@+id/img"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:src="?attr/homeIcon" />
et rend la Drawable
ic_home dans une ImageView
.
Mais je ne suis pas en mesure de comprendre comment accéder à la Drawable
par programme.
J'ai essayé de faire cela avec un contournement, en définissant un détenteur LayerList Drawable
, ce qui entraîne une exception de ressource introuvable
<?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>
Résumé Je souhaite accéder à la
Drawable
définie dans un programme personnalisé défini parTheme
.
Je pense que vous pouvez obtenir le Drawable avec ce 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();
Une autre façon possible de le faire:
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;
}
pas besoin de recycler quoi que ce soit ici ...
usage:
int drawableResId=getResIdFromAttribute(this,R.attr.homeIcon);
Drawable drawable = getResources().getDrawable(drawableResId);
J'ai utilisé la méthode ci-dessous pour obtenir l'attribut de style de formulaire d'identifiant de ressource. Ensuite, il peut être utilisé pour drawable, string, dimension etc.
TypedArray typedArray = context.getTheme().obtainStyledAttributes(new int[] { R.attr.attrName });
int resourceId = typedArray.getResourceId(0, defaultResourceId);
typedArray.recycle();
à votre santé :-)
Si vous utilisez la bibliothèque de support/conception, un moyen plus simple d’obtenir des éléments dessinables est:
Context.getDrawable(int)
ou
ContextCompat.getDrawable(Context, int)
référence - https://plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Voici les résultats de mon enquête sur ce sujet . Si nous avons declare-stylable
, nous pouvons remplacer ces valeurs dans les thèmes.
Jusqu'ici, la meilleure façon de trouver ces ressources est la suivante.
TypedArray a = context.getTheme().obtainStyledAttributes(R.styleable.AppTheme);
a.getDrawable(R.styleable.AppTheme_homeIcon);
En utilisant R.styleable.AppTheme_homeIcon
, nous référençons exactement cet attribut que nous voulons. Par exemple, si nous avons peu d'attributs en plus, nous pouvons les référencer comme suit:
a.getColor(R.styleable.AppTheme_color,defaultValue);
a.getDimension(R.styleable.AppTheme_width,defaultWidth);
Et si dans le thème actuel ces attributs n'étaient pas définis, vous obtiendrez des valeurs par défaut et aucune exception.