2012-08-05 11 views
8

Estoy trabajando en un proyecto de Android, y tengo un montón de documentos arrastrables. Estos dibujables se nombran como icon_0.png, icon_1.png ... icon_100.png. Quiero agregar todos los identificadores de recursos de estos objetos dibujables a una ArrayList de enteros. (Para aquellos que no conocen Android, solo Java, estoy hablando de variables estáticas, en una clase interna estática de una clase, como R.drawable.icon_0. Todas estas variables estáticas son enteros).Variables de acceso por nombre en un bucle

¿Hay una forma más eficiente? forma de hacer esto, que agregarlos uno por uno? Como

ArrayList<Integer> list = new ArrayList<Integer>(); 
list.add(R.drawable.icon_1); 
list.add(R.drawable.icon_2); 
... 
list.add(R.drawable.icon_100); 

¿Puedo recorrerlos de alguna manera? Al igual que

for(int i=0; i<100; i++) 
{ 
    list.add(R.drawable.icon_+i); //<--- I know this doesn't work. 
} 

tengo ningún control sobre el archivo donde estos números enteros son estáticas, y no puedo crear las dibujables en tiempo de ejecución.

¡Cualquier ayuda sería apreciada!

EDITAR

bien, leí las respuestas, pero tengo un problema importante: no tengo acceso a cualquier Context casos en los que necesito para crear esta matriz/lista de identificadores (lo hago en un bloque de inicializador estático), por lo que el método getResources(), dos de las respuestas sugeridas no funcionarán. ¿Hay otra manera de hacer esto?

+0

http://stackoverflow.com/questions/2414134/dynamically-get-drawables-by-id –

Respuesta

0

Una forma sería usar API de reflexión.

Algo a lo largo de las líneas ...

Field[] fields = R.drawable.class.getFields(); 
List<String> names = new ArrayList<String>(); 
for (Field field : fields) { 
    if(field.getName().startsWith("icon")) 
     names.add(field.getName());  
} 

int resid = getResources().getIdentifier(names.get(0), "drawable", "com.org.bla"); 

no he probado esto, pero usted consigue la idea.

+1

Mala idea ... IMO. –

+0

Me gustaría saber por qué exactamente ... – nullpotent

+0

@AljoshaBre Porque la reflexión es realmente lenta * (especialmente en Dalvik) *. Puede salirse con la suya obteniendo uno o dos residuos. En este caso, estamos hablando de 100.Si mal no recuerdo, 'getIdentifier()' también usa la reflexión internamente, lo que no mejora las cosas. Eche un vistazo a [esta pregunta] (http://stackoverflow.com/questions/5492236/why-does-reflection-slow-down-android-phone) y la [vinculada en ella] (http: // stackoverflow. com/questions/435553/java-reflection-performance). Aunque yo diría que miden y toman sus propias decisiones. Simplemente * suena * como una mala idea según mi experiencia. –

3

Puede intentar esto. YourClassName.class.getFields();

Field[] fields = R.drawable.class.getFields();

puede recorrer todos los campos, y puede que tenga que filtrarlo si tienes campos adicionales de las que necesita.

4

Cree un archivo XML en la carpeta values en su directorio resource.

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<array name="myIcons"> 
    <item>@drawable/icon1</item> 
    <item>@drawable/icon2</item> 
    <item>@drawable/icon3</item> 
    <item>@drawable/icon4</item> 
    <item>@drawable/icon5</item> 
    ... 
    ... 
</array> 
</resources> 

Siga el siguiente código, obtendrá la idea.

Resources res = getResources(); 
TypedArray myIcons= res.obtainTypedArray(R.array.myIcons); //mentioned in the XML 
for(int i=0; i<100; i++) 
{ 
    Drawable drawable = myIcons.getDrawable(i); 
    list.add(drawable); 
} 
+0

Esta es la solución correcta. Usar la reflexión es, de lejos, la peor forma de hacerlo. – Falmarri

+2

@Falmarri ¿Cuidar para explicar por qué? – nullpotent

+0

Hola! gracias por la respuesta, realmente me gusta. Mi único problema es (no lo mencioné en la pregunta), que la lista que necesito crear es un campo estático, y solo puedo cargarlo en un bloque de inicializador estático, donde no tengo acceso a ninguna instancia de contexto. Alguna idea en este caso? :( –

0

Esto es lo que terminé haciendo:

icons = new ArrayList<Integer>(100); 

//get all the fields of the R.drawable class.  
Field [] fields = R.drawable.class.getDeclaredFields(); 

//create a temporary list for the names of the needed variables. 
ArrayList <String> names = new ArrayList<String>(100); 

//select only the desired names. 
for(int i=0; i<fields.length; i++) 
    if(fields[i].getName().contains("icon_")) 
     names.add(fields[i].getName()); 

//sort these names, because later i want to access them like icons.get(0) 
//what means i want icon_0. 
Collections.sort(names); 

try 
{ 
    for(int i=0; i<names.size(); i++) 
    { 
     //get the actual value of these fields, 
     //and adding them to the icons list. 
     int id = R.drawable.class.getField(names.get(i)).getInt(null); 
     icons.add(id); 
    } 
} 
catch(Exception ex) 
{ 
    System.out.println(ex.getMessage()); 
} 

Estoy seguro, que no es la manera más rápida, sino que está funcionando. Aceptaré la solución de AljoshaBre, porque su respuesta me llevó a esta solución.

¡Gracias a todos por la ayuda!

+0

Bueno, está bien; pero espero usted es consciente de todos los pros y los contras de usar la API de reflexión en Dalvik. – nullpotent

+0

Es la segunda o la tercera vez, veo la API de reflexión en acción, así que no tengo ni idea de los beneficios/desventajas, y ni siquiera sé lo que significa Dalvik. Simplemente no quería usar el método xml, porque tenía que escribir tanto como agregar manualmente los identificadores a la lista. ¿Podría proporcionar algunas fuentes sobre Reflection? –

Cuestiones relacionadas