2010-08-23 10 views
7

Je souhaite pouvoir parcourir tous les champs du fichier R généré.Android: Itérer par programmation dans les ID de ressources

Quelque chose comme:

for(int id : R.id.getAllFields()){ 
//Do something with id, like create a view for each image 
} 

J'ai essayé la réflexion, mais je ne peux pas sembler charger une classe interne spécifique qui est contenu dans la classe R. Ainsi, par exemple, cela ne fonctionne pas pour moi:

Class c = Class.forName("packageName.R.id") 

Je peux réfléchir sur la classe R elle-même, mais je dois les champs dans la classe id.

J'ai également essayé de regarder dans la classe Ressources, mais je n'y ai rien trouvé. Dans ce cas, il semble que vous pouvez prendre un ID de ressource et obtenir le nom de chaîne de cet ID, ou prendre un nom de chaîne et obtenir l'ID de ressource correspondant. Je ne pouvais pas trouver quelque chose comme:

int[] Resources.getAllResourceIDs() 

Peut-être que je vais à ce sujet faux. Ou peut-être que je ne devrais pas combattre les taper tout dans la main, .: par exemple

int[] myIds = {R.id.firstResource, R.id.secondResource} 

Cette approche a l'inconvénient de ne pas être aussi flexible lorsque vous travaillez avec mon concepteur d'interface utilisateur. Chaque fois qu'il ajoute une nouvelle ressource au fichier XML, je vais devoir mettre à jour le code. Évidemment pas trop douloureux, mais ce serait quand même bien d'avoir et il semble que ce soit faisable.

EDIT:

La réponse ci-dessous à propos ViewGroup.getChildCount()/ViewGroup.getChildAt() fonctionne très bien. Mais, j'ai aussi dû trouver un moyen d'instancier mon XML ViewGroup/Layout. Pour ce faire, essayez quelque chose comme:

LayoutInflater li = MyActivity.getLayoutInflater(); 
ViewGroup vg = (ViewGroup) li.inflate(R.layout.main, null); 
+0

Je ne dis pas que ce soit à mon humble avis snarky mais le fait que vous sentez que vous devez poser cette question signifie que vous vous faites probablement Quelque chose ne va pas. Pouvez-vous élaborer sur votre cas d'utilisation pour ce faire. Je ne vois aucune raison pour laquelle je voudrais avoir accès à tous les identifiants définis dans toute mon application. – Qberticus

+1

Je ne veux pas accéder à tous les ID, mais plutôt à tous les ID de ressource sous un certain nom (par exemple R.imageViewIds). De cette façon, dans mon code, je peux ajouter un écouteur d'événement ou autre à chacun d'entre eux dans une boucle for.Mon interface utilisateur aura plusieurs ImageViews qui répondront tous aux événements, et ce serait bien si je pouvais accéder à tous ces ImageViews sans coder manuellement chacun par son nom (par exemple IView1.setListener (myListener); IView2.setListener (myListener);) Aussi, alors je n'aurai pas à refactoriser mon code si mon concepteur d'interface utilisateur décide de renommer les choses dans le fichier XML. –

Répondre

5

Votre réponse à mon commentaire m'a aidé à avoir une meilleure idée de ce que vous essayez de faire.

Vous pouvez probablement utiliser ViewGroup#getChildAt et ViewGroup#getChildCount à boucle à travers divers ViewGroup s dans votre hiérarchie d'affichage et d'effectuer des contrôles sur les instanceof retournés View s. Ensuite, vous pouvez faire ce que vous voulez en fonction du type de vues enfant et où ils sont dans votre hiérarchie.

+0

Cela semble être le billet! Content que la clarification ait aidé. Cela ne m'avait pas traversé l'esprit d'accéder aux vues des enfants de ma disposition. Merci beaucoup pour la perspicacité. –

+0

un exemple de code: http://stackoverflow.com/questions/4184889/android-refer-to-custom-views-in-a-loop/4185818#4185818 –

2

Vous pouvez utiliser la réflexion sur une classe interne, mais la syntaxe est packagename.R $ id. Notez que la réflexion peut être très lente et vous devriez vraiment éviter de l'utiliser.

+0

Je pensais que la réflexion pourrait être trop chère, et ne vaut pas le coup pour ne pas avoir à coder à la main certains éléments. J'espérais qu'il y avait une manière intégrée, non-relfection-basée d'accéder à ces ids, car il semble être un scénario assez commun. Merci, au moins, pour la syntaxe sur la réflexion sur les classes internes. C'est utile de savoir. –

5

J'ai trouvé que "Class.forName (getPackageName() +". R $ chaîne ");" peut vous donner accès aux ressources de chaîne et devrait fonctionner pour id, drawable, exc aussi bien.

J'utilise alors la classe trouvé comme ceci:


import java.lang.reflect.Field; 

import android.util.Log; 

public class ResourceUtil { 

    /** 
    * Finds the resource ID for the current application's resources. 
    * @param Rclass Resource class to find resource in. 
    * Example: R.string.class, R.layout.class, R.drawable.class 
    * @param name Name of the resource to search for. 
    * @return The id of the resource or -1 if not found. 
    */ 
    public static int getResourceByName(Class<?> Rclass, String name) { 
     int id = -1; 
     try { 
      if (Rclass != null) { 
       final Field field = Rclass.getField(name); 
       if (field != null) 
        id = field.getInt(null); 
      } 
     } catch (final Exception e) { 
      Log.e("GET_RESOURCE_BY_NAME: ", e.toString()); 
      e.printStackTrace(); 
     } 
     return id; 
    } 
} 
Questions connexes