Recuperando todos los recursos Drawable del objeto Resources

En mi proyecto de Android, quiero recorrer toda la colección de recursos Drawable . Normalmente, solo puede recuperar un recurso específico a través de su ID usando algo como:

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

Sin embargo, quiero obtener todos los recursos de Drawable donde no sabré su ID de antemano. ¿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 bien, ¿hay alguna manera en Java para extraer todos los valores de propiedad de la clase estática de R.drawable ?

Si te encuentras con ganas de hacer esto, probablemente estés haciendo un mal uso del sistema de recursos. Eche un vistazo a los activos y AssetManager si quiere iterar sobre los archivos incluidos en su archivo .apk.

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

 final R.drawable drawableResources = new R.drawable(); final Class 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 las llamadas de Android que no conozco, ¡definitivamente me gustaría verlas!

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

  private void getImagesIdentifiers() { int resID=0; int imgnum=1; images = new ArrayList(); do { resID=getResources().getIdentifier("img_"+imgnum, "drawable", "InsertappPackageNameHere"); if (resID!=0) images.add(resID); imgnum++; } while (resID!=0); imageMaxNumber=images.size(); } 

Le he tomado a Matt Huggins una gran respuesta y la refactoré para que sea más genérica:

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

Agregue una imagen llamada aaaa y otra llamada zzzz, luego repita lo siguiente:

 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í.

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

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 como:

  drawable1 drawable2 drawable3  

Y de tu Activity puedes obtenerlo haciendo:

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

Deberías usar la carpeta Raw y AssetManager, pero si quieres utilizar los estilos, porque no, aquí está cómo …

Supongamos que tenemos una lista de archivos muy larga de los tipos de JPG y queremos obtener todos los identificadores de recursos sin el dolor de recuperar uno por uno (R.drawable.pic1, R.drawable.pic2, … etc.)

 //first we create an array list to hold all the resources ids ArrayList imageListId = new ArrayList(); //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 } 

Solo haz esto:

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

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

 public static Map loadLayouts(){ final Class clz = R.layout.class; Map 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; } 

USE ESTE MI COD

 R.drawable drawableResources = new R.drawable(); Class 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()); } }