Comment obtenir l'ID de ressource d'une image si je connais son nom?

Réponses:

269

Avec quelque chose comme ça:

String mDrawableName = "myappicon";
int resID = getResources().getIdentifier(mDrawableName , "drawable", getPackageName());
Francesco Laurita
la source
10
Merci, cela m'a aidé à trouver une solution à un problème similaire! Je vais utiliser getResources().getIdentifier(name, "id", getPackageName());pour obtenir l'ID d'un ImageButton (comme vous le feriez avec R.id.name).
Sélectionnez le
42
Notez que le nom du dessin ne doit PAS inclure une extension comme ".png"
larham1
1
que se passe-t-il exactement dans la variable name? Je veux trouver l'identifiant d'un bouton dont je connais la référence, dans mon cas c'estbutton1
John Watson
1
getResource()et getPackageName()montrant une erreur. cannot resolve method
Srujan Barai
@Srujan Barai, getResource()et getPackageName()sont des méthodes d'Activité.
The Berga
29

Vous pouvez également essayer ceci:

try {
    Class res = R.drawable.class;
    Field field = res.getField("drawableName");
    int drawableId = field.getInt(null);
}
catch (Exception e) {
    Log.e("MyTag", "Failure to get drawable id.", e);
}

J'ai copié ces codes source à partir de l'URL ci-dessous. Sur la base des tests effectués sur cette page, il est 5 fois plus rapide que getIdentifier (). Je l'ai également trouvé plus pratique et facile à utiliser. J'espère que cela vous aidera également.

Lien: récupération dynamique des ressources sous Android

VSB
la source
2
cela pourrait être plus rapide mais j'ai trouvé que cela pouvait vous causer des ennuis si vous utilisez proguard. Cela ne fonctionne pas en proguard au moins pour moi
Pedro Rainho
Attraper des exceptions génériques est une idée particulièrement mauvaise. De plus, notez que s'il n'y a pas de références matérielles au dessinable, Proguard peut optimiser la référence car il ne pense pas qu'elle est utilisée nulle part.
Paul Lammertsma
Je comprends maintenant :) vous voulez dire que lors de l'optimisation, les changements de drawableName et la ressource ne peuvent pas être trouvés en utilisant cette méthode, si j'ai raison? :)
VSB
1
@VSB: si votre dernier commentaire est une réponse au commentaire de Paul Lammertsma immédiatement ci-dessus: Non, il signifie que Proguard ne sait pas qu'il s'agit d'une référence à la ressource, et peut donc supprimer la ressource, estimant qu'elle n'est pas utilisée.
ToolmakerSteve
une fois que vous utilisez xxxxhdpi, xxhdpi, etc., cette méthode devient moins utile
Someone Somewhere
11

Exemple pour une ressource système publique:

// this will get id for android.R.drawable.ic_dialog_alert
int id = Resources.getSystem().getIdentifier("ic_dialog_alert", "drawable", "android");

alerte

Une autre façon consiste à consulter la documentation de la classe android.R.drawable .

naXa
la source
1
@Milaaaad que voulez-vous dire?
naXa
cela signifie que je suis confus par les ressources dans le code et que je l'utilise dans une classe sans activité
Milaaaad
1
@Milaaaad Cette méthode concerne les ressources système. Ils ne dépendent pas du contexte.
naXa
10

Vous pouvez utiliser cette fonction pour obtenir un ID de ressource:

public static int getResourseId(Context context, String pVariableName, String pResourcename, String pPackageName) throws RuntimeException {
    try {
        return context.getResources().getIdentifier(pVariableName, pResourcename, pPackageName);
    } catch (Exception e) {
        throw new RuntimeException("Error getting Resource ID.", e)
    } 
}


Donc, si vous souhaitez obtenir un ID de ressource pouvant être dessiné , vous pouvez appeler la méthode comme ceci:

getResourseId(MyActivity.this, "myIcon", "drawable", getPackageName());

(ou à partir d'un fragment):

getResourseId(getActivity(), "myIcon", "drawable", getActivity().getPackageName());


Pour un ID de ressource de chaîne, vous pouvez l'appeler comme ceci:

getResourseId(getActivity(), "myAppName", "string", getActivity().getPackageName());

etc...


Attention : il lève une RuntimeException s'il ne parvient pas à trouver l'ID de ressource. Assurez-vous de récupérer correctement en production.

Lis ça

Azhar
la source
4
Je pense que vous devez supprimer staticde cela, sinon getResources()ne fonctionnera pas.
Richard Le Mesurier
@Richard Le Mesurier, peux-tu expliquer pourquoi? Je vous remercie.
Veer
1
@ Leo.Han Au moment où j'ai fait ce commentaire, le Contextn'était pas disponible. Le correctif consistait soit à le supprimer staticet à le déplacer dans un Context(par exemple Activityou Application); ou un correctif alternatif est ce que Jonathan a fait dans son édition, qui consiste à passer un Contextà la méthode.
Richard Le Mesurier
1
@Richard Le Mesurier, j'ai vérifié l'historique d'édition tout à l'heure, c'est exactement ce que vous avez dit, merci pour votre aimable réponse après tant d'années :)
Veer
0

Un autre scénario que j'ai rencontré.

String imageName = "Hello" et ensuite quand il est passé dans la fonction getIdentifier comme premier argument, il passera le nom avec la fin de la chaîne null et retournera toujours zéro. Transmettez cette imageName.substring (0, imageName.length () - 1)

sunil shah
la source