在我的Android项目中,我想遍历整个Drawable
资源集合。通常,您只能使用以下内容通过其ID检索特定资源:
InputStream is = Resources.getSystem().openRawResource(resourceId)
但是,我希望获得所有Drawable
资源,我 事先知道他们的ID。是否有一个我可以循环的集合,或者可能是一种获取资源ID列表的方法给出了我项目中的资源?
或者,Java中有没有办法从R.drawable
静态类中提取所有属性值?
答案 0 :(得分:32)
好吧,这感觉有点黑客,但这是我通过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调用,我肯定希望看到它们!
答案 1 :(得分:7)
我使用getResources()。getIdentifier来扫描资源文件夹中的顺序命名图像。为了安全起见,我决定在第一次创建活动时缓存图像ID:
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();
}
答案 2 :(得分:7)
我已经对Matt Huggins给出了很好的答案并重构了它以使其更通用:
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);
答案 3 :(得分:5)
如果您发现自己想要这样做,那么您可能会滥用资源系统。如果要迭代.apk中包含的文件,请查看资产和AssetManager
。
答案 4 :(得分: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
}
}
这对我有用。
答案 5 :(得分:4)
你应该使用Raw文件夹和AssetManager,但如果你想使用drawables,为什么不这样,这里是如何......
假设我们有一个非常长的JPG drawable文件列表,我们希望获得所有资源ID,而不必逐个检索(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
}
答案 6 :(得分:3)
我想反射代码会起作用,但我不明白为什么你需要它。
安装应用程序后,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 :(得分:2)
这样做:
Field[] declaredFields = (R.drawable.class).getDeclaredFields();
答案 8 :(得分:0)
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;
}
答案 9 :(得分:0)
使用此代码
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());
}
}
答案 10 :(得分:0)
要在Kotlin中创建一系列可绘制对象:
val drawablesFields: Array<Field> = drawable::class.java.fields
val drawables: ArrayList<Drawable> = ArrayList()
for (field in drawablesFields) {
context?.let { ContextCompat.getDrawable(it, field.getInt(null)) }?.let {
drawables.add (
it
)
}
}