2010-07-11 23 views
20

En mi proyecto de Android, quiero recorrer toda la colección de recursos de Drawable. Normalmente, sólo se puede recuperar un recurso específico a través de su ID de usar algo como:Recuperando todos los recursos extraíbles del objeto de recursos

InputStream is = Resources.getSystem().openRawResource(resourceId) 

Sin embargo, quiero conseguir todos los recursos Drawable donde no a saber de antemano su identificación. ¿Hay una colección en la que pueda acceder a través de un bucle o quizás una forma de obtener la lista de ID de recursos con los recursos de mi proyecto?

O, ¿hay alguna manera para mí en Java para extraer todos los valores de propiedad de la clase estática R.drawable?

Respuesta

6

Si usted se encuentra con ganas de hacer esto es probable que estés haciendo mal uso de recursos del sistema. Eche un vistazo a assets y AssetManager si desea iterar sobre archivos incluidos en su archivo .apk.

+0

Gracias, lo comprobaré. Estoy intentando cargar texturas en la memoria para usarlas en un juego OpenGL. –

+1

Esto funciona y es menos específico del proyecto (debido a que la clase 'R' es específica del proyecto), que me gusta. La única diferencia es que tengo que usar la carpeta "assets" en lugar de la carpeta "res". –

31

Bueno, esto se siente un poco hack-ish, pero esto es lo que se me ocurrió a través de Reflection. (Tenga en cuenta que resources es una instancia de la clase android.content.res.Resources.)

final R.drawable drawableResources = new R.drawable(); 
final Class<R.drawable> c = R.drawable.class; 
final Field[] fields = c.getDeclaredFields(); 

for (int i = 0, max = fields.length; i < max; i++) { 
    final int resourceId; 
    try { 
     resourceId = fields[i].getInt(drawableResources); 
    } catch (Exception e) { 
     continue; 
    } 
    /* make use of resourceId for accessing Drawables here */ 
} 

Si alguien tiene una mejor solución que hace un mejor uso de Android llamadas podría no tener en cuenta, sin duda me gustaría verlos!

+5

Esta es la única forma de obtener recursos (en lugar de recursos) que puedo encontrar. Tenga en cuenta que no necesita DrawableResources. Como todos los campos de R son estáticos, getInt() puede tomar nulo. –

+0

Esto funciona muy bien, gracias por compartir :-) – magritte

+0

Solo un detalle a tener en cuenta: 'java.lang.reflect.Field' –

3

Supongo que el código de reflexión funcionará, pero no entiendo por qué lo necesita.

Los recursos en Android son estáticos una vez que se instala la aplicación para que pueda tener una lista de recursos o una matriz. Algo así como:

<string-array name="drawables_list"> 
    <item>drawable1</item> 
    <item>drawable2</item> 
    <item>drawable3</item> 
</string-array> 

Y desde su Activity lo puede conseguir haciendo:

getResources().getStringArray(R.array.drawables_list); 
+5

Esto funciona, pero el problema es que cada vez que agrego un dibujable a la carpeta, también tengo que actualizar esta matriz de cadenas. Estoy buscando algo más automático. –

7

utilicé getResources(). GetIdentifier para escanear a través de imágenes con nombre secuencial en mis carpetas de recursos. estar en un lado seguro, decidí almacenar en caché los identificadores de imagen cuando se crea la actividad primera vez:

private void getImagesIdentifiers() { 

    int resID=0;   
    int imgnum=1; 
    images = new ArrayList<Integer>(); 

    do {    
     resID=getResources().getIdentifier("img_"+imgnum, "drawable", "InsertappPackageNameHere"); 
     if (resID!=0) 
      images.add(resID); 
     imgnum++; 
    } 
    while (resID!=0); 

    imageMaxNumber=images.size(); 
} 
4

he tomado Matt Huggins gran respuesta y refactorizado él para que sea más genérico:

public static void loadDrawables(Class<?> clz){ 
    final Field[] fields = clz.getDeclaredFields(); 
    for (Field field : fields) { 
     final int drawableId; 
     try { 
      drawableId = field.getInt(clz); 
     } catch (Exception e) { 
      continue; 
     } 
     /* make use of drawableId for accessing Drawables here */ 
    } 
} 

uso:

loadDrawables(R.drawable.class); 
+0

Esa es la mejor solución, gracias –

4

Añadir una fotografía denominada AAAA y otro llamado zzzz, a continuación, iterar a través de los siguientes:

public static void loadDrawables() { 
    for(long identifier = (R.drawable.aaaa + 1); 
     identifier <= (R.drawable.zzzz - 1); 
     identifier++) { 
    String name = getResources().getResourceEntryName(identifier); 
    //name is the file name without the extension, indentifier is the resource ID 
    } 
} 

Esto funcionó para mí.

+2

Me gusta la creatividad detrás de este truco. ;) –

+0

¡Buena creatividad! : D –

+0

¡Qué creatividad! Muchas gracias –

2

a hacer esto:

Field[] declaredFields = (R.drawable.class).getDeclaredFields(); 
+1

¿Y cómo obtiene el recurso del objeto de campo? –

+1

Puede escribir un código como este: imageView.setImageDrawable (Utils.getDrawable (declaredFields.get (position) .getName(), context)) – Alecs

0

El PO quería y necesitaba dibujables diseños. Esto es lo que se me ocurrió para los diseños. El negocio name.startsWith me permite ignorar los diseños generados por el sistema, por lo que puede necesitar modificarlo un poco. Esto debería funcionar para cualquier tipo de recurso modificando el valor de clz.

public static Map<String,Integer> loadLayouts(){ 
    final Class<?> clz = R.layout.class; 
    Map<String,Integer> layouts = new HashMap<>(); 
    final Field[] fields = clz.getDeclaredFields(); 
    for (Field field : fields) { 
     String name = field.getName(); 
     if (
       !name.startsWith("abc_") 
       && !name.startsWith("design_") 
       && !name.startsWith("notification_") 
       && !name.startsWith("select_dialog_") 
       && !name.startsWith("support_") 
     ) { 
      try { 
       layouts.put(field.getName(), field.getInt(clz)); 
      } catch (Exception e) { 
       continue; 
      } 
     } 
    } 
    return layouts; 
} 
3

Se debe utilizar la carpeta de Raw y AssetManager, pero si desea utilizar dibujables porque ¿por qué no, aquí es cómo ...

Supongamos que tenemos una lista muy larga de archivo JPG y dibujables queremos obtener todos los ID de los recursos sin el dolor de la recuperación de uno a uno (R.drawable.pic1, R.drawable.pic2, etc ...)

//first we create an array list to hold all the resources ids 
ArrayList<Integer> imageListId = new ArrayList<Integer>(); 

//we iterate through all the items in the drawable folder 
Field[] drawables = R.drawable.class.getFields(); 
for (Field f : drawables) { 
    //if the drawable name contains "pic" in the filename... 
    if (f.getName().contains("image")) 
     imageListId.add(getResources().getIdentifier(f.getName(), "drawable", getPackageName())); 
} 

//now the ArrayList "imageListId" holds all ours image resource ids 
for (int imgResourceId : imageListId) { 
    //do whatever you want here 
} 
0

USO ESTA MI CÓDIGO

R.drawable drawableResources = new R.drawable(); 
Class<R.drawable> c = R.drawable.class; 
Field[] fields = c.getDeclaredFields(); 

for (int i = 0, max = fields.length; i < max; i++) { 
    final int resourceId; 
    try { 
     resourceId = fields[i].getInt(drawableResources); 
     // call save with param of resourceId 
     SaveImage(resourceId); 
    } catch (Exception e) { 
     continue; 
    } 
} 

... 

public void SaveImage(int resId){ 
    if (!CheckExternalStorage()) { 
     return; 
    } 

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), resID); 
    try { 
     File dir = new File(path); 
     if (!dir.exists()) { 
      dir.mkdirs(); 
     } 
     OutputStream fOut = null; 
     File file = new File(path, "image1.png"); 
     file.createNewFile(); 
     fOut = new FileOutputStream(file); 
     bmp.compress(Bitmap.CompressFormat.PNG, 100, fOut); 
     fOut.flush(); 
     fOut.close(); 
     MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName()); 
     Log.i(LOGTAG, "Image Written to Exterbal Storage"); 

    } catch (Exception e) { 
     Log.e("saveToExternalStorage()", e.getMessage()); 
    } 
} 
Cuestiones relacionadas