Подтвердить что ты не робот

Извлечение всех ресурсов Drawable из объекта Resources

В моем Android-проекте я хочу пропустить всю коллекцию ресурсов Drawable. Обычно вы можете получить только определенный ресурс через свой идентификатор, используя что-то вроде:

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

Однако я хочу получить все ресурсы Drawable, где я не будет знать свой идентификатор заранее. Есть ли коллекция, через которую я могу пройти или, возможно, получить список идентификаторов ресурсов, учитывая ресурсы в моем проекте?

Или, есть ли способ для меня в Java извлечь все значения свойств из статического класса R.drawable?

4b9b3361

Ответ 1

Если вы обнаружите, что хотите сделать это, вы, вероятно, злоупотребляете системой ресурсов. Взгляните на активы и AssetManager, если вы хотите перебирать файлы, включенные в ваш .apk.

Ответ 2

Хорошо, это немного взломанно, но это то, что я придумал с помощью Reflection. (Обратите внимание, что resources является экземпляром класса 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 */
}

Если у кого-то есть лучшее решение, которое лучше использует вызовы Android, о которых я, возможно, и не подозревал, я определенно хотел бы их увидеть!

Ответ 3

Я использовал getResources(). getIdentifier для сканирования последовательно названных изображений в папках ресурсов. чтобы быть в безопасности, я решил кэшировать идентификаторы изображений, когда активность создается в первый раз:

    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

Я принял Мэтта Хаггинса отличный ответ и реорганизовал его, чтобы сделать его более общим:

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

Использование:

loadDrawables(R.drawable.class);

Ответ 5

Добавьте изображение с именем aaaa и другим именем zzzz, затем выполните следующие действия:

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

Это сработало для меня.

Ответ 6

Я думаю, что код отражения будет работать, но я не понимаю, зачем вам это нужно.

Ресурсы в Android являются статическими, когда приложение установлено, поэтому вы можете иметь список ресурсов или массив. Что-то вроде:
<string-array name="drawables_list">
    <item>drawable1</item>
    <item>drawable2</item>
    <item>drawable3</item>
</string-array>

И из вашего Activity вы можете получить его, выполнив:

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

Ответ 7

Вы должны использовать папку Raw и AssetManager, но если вы хотите использовать drawables, потому что почему бы и нет, вот как...

Предположим, что у нас очень длинный список файлов JPG-чертежей, и мы хотим получить все идентификаторы ресурсов без боли при поиске по одному (R.drawable.pic1, R.drawable.pic2,... и т.д.).

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

Ответ 8

Просто сделайте следующее:

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

Ответ 9

OP нуждался в чертежах, и мне нужны макеты. Это то, что я придумал для макетов. Бизнес name.startsWith позволяет мне игнорировать сгенерированные системой макеты, поэтому вам может потребоваться немного изменить его. Это должно работать для любого типа ресурса, изменяя значение 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;
}

Ответ 10

ИСПОЛЬЗУЙТЕ ЭТО МОЙ КОД

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