【问题标题】:Is there a way to iterate through R.drawable?有没有办法遍历 R.drawable?
【发布时间】:2021-06-18 08:21:30
【问题描述】:

我有很多可绘制的图像,我希望将它们放入一个数组中。手动将它们放入数组将花费太长时间,无论是时间还是代码。我想知道是否有办法循环通过R.drawable,像这样:

ArrayList<Integer> imgArr = new ArrayList<>();
for(int k=0; k<R.drawable.size(); k++) {
    imgArr.add(R.drawable.get(k));
}

【问题讨论】:

  • "手动将它们放入数组中将花费太长的时间和代码。" 将它们放入 ArrayList 的速度如何更快?
  • 我明白我没有说清楚。我的意思是,不是将所有文件名输入到数组或数组列表中,而是有一种方法可以循环遍历 R.drawable 而无需指定图像文件名。
  • 我不认为资源应该是这样工作的。也许使用资产文件夹更适合您?见:stackoverflow.com/a/3224478/12622119

标签: java android android-drawable


【解决方案1】:

首先你应该对R类有点了解:Read more here

简而言之:R 类是一个动态生成的类,其中包含内部类(例如 drawable 类)。这些内部类包含多个Integer常量,它们链接到对应的资源

这意味着,由于这里的可绘制对象被定义为R.drawable 类的成员,我们需要使用反射来访问它们。 首先,我们需要获取drawable 子类的一个实例。不幸的是,这个类的构造函数是私有的,但是我们可以通过更多的反射来解决这个问题:

Class<R.drawable> drawableClass = R.drawable.class;
R.drawable instance = (R.drawable) drawableClass.getConstructors()[0].newInstance();

接下来我们创建一个 ArrayList 并为在 R.drawable 类中声明的每个字段我们获取在我们的实例中设置的值(因为它们是常量,它们将是正确的值)并将其添加到列表:

List<Integer> drawables = new ArrayList<>();
for (Field field :
    drawableClass.getDeclaredFields()) {
    int value = field.getInt(instance);
    drawables.add(value);
}

这已经完成了所有需要的代码,你现在可以正常使用列表中的整数,就像你使用R.drawable.icon一样。但是请注意,getDeclaredConstructors()newInstance()getDeclaredFields()getInt() 都会抛出需要捕获的异常。

完整片段(Java):

public static List<Integer> getDrawablesList() throws IllegalAccessException, InvocationTargetException, InstantiationException {
    Class<R.drawable> drawableClass = R.drawable.class;
    R.drawable instance = (R.drawable) drawableClass.getDeclaredConstructors()[0].newInstance();
    List<Integer> drawables = new ArrayList<>();
    for (Field field :
            drawableClass.getDeclaredFields()) {
        int value = field.getInt(instance);
        drawables.add(value);
    }
    return drawables;
}

完整片段(Kotlin):

(需要“org.jetbrains.kotlin:kotlin-reflect:YOUR_KOTLIN_VERSION”依赖)

private fun getDrawablesList() : List<Int> {
    val drawableClass = R.drawable::class
    val instance = drawableClass.constructors.first().call()
    val drawablesList = mutableListOf<Int>()
    for (field in instance.javaClass.declaredFields) {
        val test = field.getInt(instance)
        drawablesList.add(test)
    }
    return drawablesList
}

【讨论】:

  • 哦,这很有意义,哇。非常感谢您的精彩解释!
  • 我曾使用此方法列出我的应用程序上的所有可绘制对象,但现在,在 Android 11 (Api 30) 上似乎不再工作,可能是因为新的 api 不允许使用反射.
猜你喜欢
  • 2010-11-20
  • 2016-01-16
  • 2016-05-03
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
相关资源
最近更新 更多