2010-12-13 34 views
119

Je dois passer un ID de ressource à une méthode dans l'une de mes classes. Il doit utiliser à la fois l'identifiant que la référence pointe vers et il a également besoin de la chaîne. Comment devrais-je le faire mieux?Android, obtenir l'ID de la ressource de la chaîne?

Par exemple:

R.drawable.icon 

je dois obtenir l'ID entier de cela, mais je dois aussi l'accès à la chaîne « icône ».

Il serait préférable que tout ce que je devais passer à la méthode est la chaîne "icône".

+0

est-il possible de manière similaire à getId des fichiers enregistrés dans la mémoire interne? J'ai un problème parce que je devrais fournir un tableau d'ids au lieu d'emplacements à ma galerie (pensé c'est adaptateur) .. merci – Ewoks

+0

@Ewoks: Ils n'ont pas d'ID sur le stockage interne. Ce ne sont que des images, si vous avez besoin de les charger dans un tas d'objets Image et de les transmettre, vous pouvez cependant commencer une nouvelle question. – Hamid

+0

duplicata possible de [Comment obtenir un ID de ressource avec un nom de ressource connu?] (Http://stackoverflow.com/questions/3476430/how-to-get-a-resource-id-with-a-known-resource -name) –

Répondre

134

@EboMike: Je ne savais pas que Resources.getIdentifier() existait.

Dans mes projets, j'utilisé le code suivant pour le faire:

public static int getResId(String resName, Class<?> c) { 

    try { 
     Field idField = c.getDeclaredField(resName); 
     return idField.getInt(idField); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return -1; 
    } 
} 

Il serait utilisé comme ceci:

getResId("icon", Drawable.class); 

Je viens de trouver un billet de blog en disant que Resources.getIdentifier() est plus lent que réflexion comme je l'ai fait. Check it out.

+7

@Macarse: Actuellement, 'getIdentifier()' doit effectuer deux recherches de réflexion. Dans votre exemple ci-dessus, 'getIdentifier()' utiliserait la réflexion pour obtenir 'Drawable.class', puis une autre recherche de réflexion pour obtenir l'ID de la ressource. Cela expliquerait la différence de vitesse. Cela étant dit, ni l'un ni l'autre ne sont particulièrement rapides et ont donc vraiment besoin d'être mis en cache (en particulier s'il est utilisé dans une boucle, ou pour des lignes dans un ListView). Et le gros problème de l'approche par réflexion est qu'elle fait des suppositions sur les composants internes d'Android qui pourraient changer dans une future version. – CommonsWare

+1

@CommonsWare: C'est vrai. Je vérifiais comment Android mis en œuvre et il finit ups étant un appel natif. http://gitorious.org/android-eeepc/base/blobs/3661101005c6527dfd384d0c88c4a3b68ee208af/core/java/android/content/res/Resources.java#line1346 => http: // gitorious.org/android-eeepc/base/blobs/3661101005c6527dfd384d0c88c4a3b68ee208af/noyau/java/android/content/res/AssetManager.java # line609 – Macarse

+0

Désolé les gars, je ne vois toujours pas une réponse acceptable. Je veux minimiser les paramètres ne les augmente pas. que se passe-t-il si je passe l'ID de ressource (R.drawable.icon) sous la forme d'un entier, puis-je utiliser l'identifiant pour obtenir le nom de la ressource et supprimer la partie dont j'ai besoin pour obtenir l'icône? – Hamid

9

Vous pouvez utiliser Resources.getIdentifier(), bien que vous deviez utiliser le format de votre chaîne tel que vous l'utilisez dans vos fichiers XML, c'est-à-dire package:drawable/icon.

+0

Ma réponse ci-dessous est l'inverse de ceci. Passez l'ID de ressource, puis utilisez 'getResourceEntryName (id)' pour trouver le nom de la chaîne. Pas de déconner pour trouver "icône" du texte plus long. –

9

Si vous devez jumeler une chaîne et un int, que diriez-vous d'une carte?

static Map<String, Integer> icons = new HashMap<String, Integer>(); 

static { 
    icons.add("icon1", R.drawable.icon); 
    icons.add("icon2", R.drawable.othericon); 
    icons.add("someicon", R.drawable.whatever); 
} 
28

Comment obtenir une application id ressource à partir du nom de la ressource est une question tout à fait commune et bien répondu.

Comment obtenir un natif Android ID de ressource du nom de ressource est moins bien répondu. Voilà ma solution pour obtenir une ressource drawable Android par nom de la ressource:

public static Drawable getAndroidDrawable(String pDrawableName){ 
    int resourceId=Resources.getSystem().getIdentifier(pDrawableName, "drawable", "android"); 
    if(resourceId==0){ 
     return null; 
    } else { 
     return Resources.getSystem().getDrawable(resourceId); 
    } 
} 

La méthode peut être modifié pour accéder à d'autres types de ressources.

+0

maintenant .getResources(). GetDrawable est dépréciée 'if (android.os.Build.VERSION.SDK_INT> = android.os.Build.VERSION_CODES.LOLLIPOP) { \t \t \t \t return mContext.getDrawable (resourceId); \t \t \t} else { \t \t \t \t mContext.getResources de retour() getDrawable (resourceId). \t \t \t} ' – Evilripper

33

Ceci est basé sur la réponse @Macarse.

Utilisez ceci pour obtenir les ressources Id d'une manière plus rapide et conviviale.

public static int getId(String resourceName, Class<?> c) { 
    try { 
     Field idField = c.getDeclaredField(resourceName); 
     return idField.getInt(idField); 
    } catch (Exception e) { 
     throw new RuntimeException("No resource ID found for: " 
       + resourceName + "/" + c, e); 
    } 
} 

Exemple:

getId("icon", R.drawable.class); 
+7

Ceci est le code qui a fonctionné. pas le buggy ci-dessus! – hasan83

5

Je l'ai fait comme ça, il travaille pour moi:

imageView.setImageResource(context.getResources(). 
     getIdentifier("drawable/apple", null, context.getPackageName())); 
57

Vous pouvez utiliser cette fonction pour obtenir ID de ressource.

public static int getResourceId(String pVariableName, String pResourcename, String pPackageName) 
{ 
    try { 
     return getResources().getIdentifier(pVariableName, pResourcename, pPackageName); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return -1; 
    } 
} 

Donc, si vous voulez obtenir pour drawable fonction d'appel comme celui-ci

getResourceId("myIcon", "drawable", getPackageName()); 

et chaîne que vous pouvez l'appeler comme ça

getResourceId("myAppName", "string", getPackageName()); 

Read this

+1

pour que cela fonctionne, j'ai dû supprimer 'static' – fersarr

+4

Quel est le point de faire une fonction qui appelle simplement un autre et "gère" une éventuelle exception? Appelez getResources(). GetIdentifier() directement. –

2

Depuis vous avez dit que vous vouliez seulement passer un p arameter et il ne semble pas à la matière qui, vous pouvez passer l'identifiant de ressource et puis trouver le nom de chaîne pour elle, ainsi:

String name = getResources().getResourceEntryName(id); 

Cela pourrait être la façon la plus efficace d'obtenir les deux valeurs. Vous n'avez pas à chercher la partie "icône" d'une chaîne plus longue.

4

Un moyen simple d'obtenir l'ID de ressource à partir d'une chaîne. Ici nom_ressource est le nom de la ressource ImageView dans un dossier pouvant être tracé qui est également inclus dans le fichier XML.

int resID = getResources().getIdentifier(resourceName, "id", getPackageName()); 
ImageView im = (ImageView) findViewById(resID); 
Context context = im.getContext(); 
int id = context.getResources().getIdentifier(resourceName, "drawable", 
context.getPackageName()); 
im.setImageResource(id); 
+0

Merci l'homme c'était vraiment utile .. J'ai cherché beaucoup et je n'ai pas réussi. En voyant votre réponse, j'ai trouvé que le second paramètre de 'getIdentifier' doit être' id'. Ce n'était même pas mentionné dans le site de développement Android. Où avez-vous eu cette information? –

1

En MonoDroid/Xamarin.Android vous pouvez faire:

var resourceId = Resources.GetIdentifier("icon", "drawable", PackageName); 

Mais depuis DonneIdentifiant il n'est pas recommandé dans Android - vous pouvez utiliser comme Reflection ceci:

var resourceId = (int)typeof(Resource.Drawable).GetField("icon").GetValue(null); 

où Je suggère de mettre un essai/attraper ou vérifier les chaînes que vous passez.

0

Pour obtenir un ID Drawable de chaîne nom de ressource J'utilise ce code:

private int getResId(String resName) { 
    int defId = -1; 
    try { 
     Field f = R.drawable.class.getDeclaredField(resName); 
     Field def = R.drawable.class.getDeclaredField("transparent_flag"); 
     defId = def.getInt(null); 
     return f.getInt(null); 
    } catch (NoSuchFieldException | IllegalAccessException e) { 
     return defId; 
    } 
} 
1
public int getDrawableName(Context ctx,String str){ 
    return ctx.getResources().getIdentifier(str,"drawable",ctx.getPackageName()); 

} 
+0

Serait mieux si vous donnez juste plus d'informations à votre réponse. – xMRi