web-dev-qa-db-fra.com

Ressource d'accès définie dans theme et attrs.xml android

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 par Theme.

33
Shardul

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();
68
dmaxi

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);
9
android developer

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é :-)

2
dheeran

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

1
Parag Naik

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.

0
Lemberg