web-dev-qa-db-fra.com

Récupérer toutes les ressources Drawable de l'objet Resources

Dans mon projet Android, je souhaite parcourir toute la collection de ressources Drawable. Normalement, vous ne pouvez récupérer une ressource spécifique via son ID en utilisant quelque chose comme:

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

Cependant, je veux obtenir toutes les ressources Drawable où je ne veux pas je ne connais pas leur identifiant auparavant. Existe-t-il une collection que je peux parcourir ou peut-être un moyen d'obtenir la liste des identifiants de ressources en fonction des ressources de mon projet?

Ou bien, est-il possible pour Java d’extraire toutes les valeurs de propriété de la classe statique R.drawable?

21
Matt Huggins

Si vous avez envie de faire cela, vous utilisez probablement mal le système de ressources. Examinez les ressources et AssetManager si vous souhaitez effectuer une itération sur les fichiers inclus dans votre .apk.

6
adamp

D'accord, cela semble un peu bidon, mais c'est ce que j'ai proposé avec Reflection. (Notez que resources est une instance de la classe 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 quelqu'un a une meilleure solution qui exploite mieux les appels Android dont je n'ai peut-être pas connaissance, j'aimerais vraiment les voir!

31
Matt Huggins

J'ai pris la bonne réponse de Matt Huggins et je l'ai refactorisée pour la rendre plus générique:

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 */
    }   
}

Usage:

loadDrawables(R.drawable.class);
7

j'ai utilisé getResources (). getIdentifier pour parcourir des images nommées de manière séquentielle dans mes dossiers de ressources. Pour être sûr, j'ai décidé de mettre en cache les identifiants d'image lorsque l'activité est créée pour la première fois:

    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();
}
7
mishkin

Ajoutez une image nommée aaaa et un autre nommé zzzz, puis parcourez les éléments suivants:

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

Cela a fonctionné pour moi.

5
Mikaël Mayer

Vous devriez utiliser le dossier Raw et AssetManager, mais si vous voulez utiliser des objets dessinables parce que pourquoi pas, voici comment ...

Supposons que nous ayons une très longue liste de fichiers dessinables au format JPG et que nous souhaitons obtenir tous les identifiants de ressources sans la peine de les récupérer un par un (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
}
3
D.Snap

Je suppose que le code de réflexion fonctionnera mais je ne comprends pas pourquoi vous en avez besoin.

Les ressources dans Android sont statiques une fois l'application installée, vous pouvez donc avoir une liste de ressources ou un tableau. Quelque chose comme:

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

Et à partir de votre Activity, vous pouvez l'obtenir en faisant:

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

Faites juste ceci:

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

Le PO voulait des tirages et j'avais besoin de dispositions. C'est ce que je suis venu avec pour les mises en page. L’entreprise name.startsWith me permet d’ignorer les mises en page générées par le système. Vous devrez peut-être modifier un peu cela. Cela devrait fonctionner pour tout type de ressource en modifiant la valeur 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;
}
0
JohnnyLambada

UTILISER CE CODE MON

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());
    }
}
0
user7616371