Ответ 1
Если вы обнаружите, что хотите сделать это, вы, вероятно, злоупотребляете системой ресурсов. Взгляните на активы и AssetManager
, если вы хотите перебирать файлы, включенные в ваш .apk.
В моем Android-проекте я хочу пропустить всю коллекцию ресурсов Drawable
. Обычно вы можете получить только определенный ресурс через свой идентификатор, используя что-то вроде:
InputStream is = Resources.getSystem().openRawResource(resourceId)
Однако я хочу получить все ресурсы Drawable
, где я не будет знать свой идентификатор заранее. Есть ли коллекция, через которую я могу пройти или, возможно, получить список идентификаторов ресурсов, учитывая ресурсы в моем проекте?
Или, есть ли способ для меня в Java извлечь все значения свойств из статического класса R.drawable
?
Если вы обнаружите, что хотите сделать это, вы, вероятно, злоупотребляете системой ресурсов. Взгляните на активы и AssetManager
, если вы хотите перебирать файлы, включенные в ваш .apk.
Хорошо, это немного взломанно, но это то, что я придумал с помощью 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, о которых я, возможно, и не подозревал, я определенно хотел бы их увидеть!
Я использовал 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();
}
Я принял Мэтта Хаггинса отличный ответ и реорганизовал его, чтобы сделать его более общим:
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);
Добавьте изображение с именем 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
}
}
Это сработало для меня.
Я думаю, что код отражения будет работать, но я не понимаю, зачем вам это нужно.
Ресурсы в Android являются статическими, когда приложение установлено, поэтому вы можете иметь список ресурсов или массив. Что-то вроде:<string-array name="drawables_list">
<item>drawable1</item>
<item>drawable2</item>
<item>drawable3</item>
</string-array>
И из вашего Activity
вы можете получить его, выполнив:
getResources().getStringArray(R.array.drawables_list);
Вы должны использовать папку 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
}
Просто сделайте следующее:
Field[] declaredFields = (R.drawable.class).getDeclaredFields();
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;
}
ИСПОЛЬЗУЙТЕ ЭТО МОЙ КОД
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());
}
}