2010-08-23 5 views
7

Ich möchte in der Lage sein, durch alle Felder in der generierten R-Datei zu durchlaufen.Android: Programmatisch iterieren durch Ressource-IDs

Etwas wie:

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

Ich habe Reflexion versucht, aber ich kann nicht eine bestimmte innere Klasse zu laden scheinen, die in der R-Klasse enthalten ist. So zum Beispiel würde dies nicht für mich arbeiten:

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

ich auf der R-Klasse reflektieren kann mich, aber ich brauche die Felder innerhalb der ID-Klasse.

Ich habe auch versucht, durch die Ressourcen-Klasse zu suchen, konnte aber nichts dort finden. In diesem Fall scheint es, dass Sie eine resourceID nehmen und den String-Namen dieser ID erhalten oder einen String-Namen und die entsprechende resourceID erhalten können. Ich konnte nichts finden wie:

int[] Resources.getAllResourceIDs() 

Vielleicht gehe ich über das falsch. Oder vielleicht kämpfen, ich sollte sie nicht alle in von Hand eingeben, z.B .:

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

Dieser Ansatz hat den Nachteil nicht so flexibel zu sein, wenn sie mit meinem UI-Designer zu arbeiten. Immer wenn er der XML-Datei eine neue Ressource hinzufügt, muss ich den Code aktualisieren. Offensichtlich nicht zu schmerzhaft, aber es wäre immer noch nett zu haben und es scheint, als ob es machbar sein könnte.

EDIT:

Die Antwort unter etwa ViewGroup.getChildCount()/ViewGroup.getChildAt() funktioniert gut. Aber ich musste auch eine Möglichkeit finden, meine XML ViewGroup/Layout zu instanziieren. Um das zu tun, versuchen Sie so etwas wie:

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

ich diese snarky, um nicht zu sagen, aber meiner Meinung nach die Tatsache, dass Sie das Gefühl, Sie müssen diese Frage stellen bedeutet, dass Sie wahrscheinlich tun etwas stimmt nicht. Können Sie Ihren Anwendungsfall dafür näher erläutern? Ich kann mir einfach keinen Grund vorstellen, warum ich während meiner gesamten Bewerbung auf alle IDs zugreifen möchte. – Qberticus

+1

Ich möchte nicht auf alle IDs zugreifen, sondern auf alle Ressourcen-IDs unter einem bestimmten Namen (z. B. R.imageViewIds). Auf diese Weise kann ich in meinem Code einen Ereignis-Listener oder was auch immer hinzufügen.Meine Benutzeroberfläche wird mehrere ImageViews haben, die alle auf Ereignisse reagieren, und es wäre nett, wenn ich auf alle diese ImageViews zugreifen könnte, ohne jedes mit dem Namen manuell zu codieren (zB IView1.setListener (myListener); IView2.setListener (myListener);) Auch dann muss ich meinen Code nicht umgestalten, wenn mein UI-Designer beschließt, Dinge in der XML-Datei umzubenennen. –

Antwort

5

Ihre Antwort auf meinen Kommentar hat mir geholfen, eine bessere Vorstellung davon zu bekommen, was Sie vorhaben.

Sie können sich wahrscheinlich ViewGroup#getChildAt und ViewGroup#getChildCount eine Schleife durch verschiedene ViewGroup s in Ihrer Ansicht Hierarchie verwenden und instanceof Kontrollen der zurück View s durchführen. Dann können Sie tun, was Sie wollen, abhängig vom Typ der untergeordneten Ansichten und davon, wo sie sich in Ihrer Hierarchie befinden.

+0

Das scheint das Ticket zu sein! Froh, dass die Aufklärung geholfen hat. Es war mir nicht in den Sinn gekommen, auf die Kinderansichten meines Layouts zuzugreifen. Vielen Dank für die Einsicht. –

+0

ein Codebeispiel: http://stackoverflow.com/questions/4184889/android-refer-to-custom-views-in-a-loop/4185818#4185818 –

2

Sie können Reflexion an einer inneren Klasse verwenden, aber die Syntax ist packagename.R $ id. Beachten Sie, dass die Reflexion sehr langsam sein kann, und Sie sollten es WIRKLICH vermeiden.

+0

Ich dachte, dass Reflexion zu teuer sein könnte, und es nicht wert nur für die Bequemlichkeit, einige Artikel nicht manuell codieren zu müssen. Ich hatte gehofft, dass es einen eingebauten, nicht relefektionsbasierten Zugang zu diesen IDs gibt, da es sich um ein Szenario handelt, das häufig genug ist. Danke zumindest für die Syntax beim Nachdenken über innere Klassen. Es ist nützlich zu wissen. –

5

Ich fand, dass "Class.forName (getPackageName() +". R $ string ");" kann Ihnen Zugriff auf die String-Ressourcen geben und sollte für ID, Drawable, Exc auch arbeiten.

ich dann die Klasse wie folgt gefunden:


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; 
    } 
}