【问题标题】:Access variables by name in a loop在循环中按名称访问变量
【发布时间】:2012-08-05 06:40:55
【问题描述】:

我正在开发一个 Android 项目,并且我有很多可绘制对象。这些drawables都被命名为icon_0.png,icon_1.png ... icon_100.png。我想将这些可绘制对象的所有资源 ID 添加到整数的 ArrayList 中。 (对于那些不了解android,只知道Java的人,我说的是静态变量,在一个类的静态内部类中,比如R.drawable.icon_0。所有这些静态变量都是整数。)

有没有比逐个添加更有效的方法?喜欢

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(R.drawable.icon_1);
list.add(R.drawable.icon_2);
...
list.add(R.drawable.icon_100);

我可以以某种方式遍历它们吗?喜欢

for(int i=0; i<100; i++)
{
    list.add(R.drawable.icon_+i);  //<--- I know this doesn't work.
}

我无法控制这些静态整数所在的文件,并且我无法在运行时创建可绘制对象。

任何帮助将不胜感激!

编辑

好的,我阅读了答案,但我有一个主要问题:我无权访问任何需要创建此 ID 数组/列表的 Context 实例(我在静态初始化程序块中执行此操作) ,所以 getResources() 方法,其中两个建议的答案不起作用。有没有其他方法可以做到这一点?

【问题讨论】:

标签: java android


【解决方案1】:

在resource 目录的values 文件夹中创建一个XML 文件。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="myIcons">
    <item>@drawable/icon1</item>
    <item>@drawable/icon2</item>
    <item>@drawable/icon3</item>
    <item>@drawable/icon4</item>
    <item>@drawable/icon5</item>
    ...
    ...
</array>
</resources>

通过下面的代码,你就会明白了。

Resources res = getResources();
TypedArray myIcons= res.obtainTypedArray(R.array.myIcons);  //mentioned  in the XML
for(int i=0; i<100; i++)
{
    Drawable drawable = myIcons.getDrawable(i);
    list.add(drawable);  
}

【讨论】:

  • 这是正确的解决方案。到目前为止,使用反射是最糟糕的方法。
  • @Falmarri 想解释一下原因?
  • 嗨!谢谢你的回答,我真的很喜欢。我唯一的问题是(我没有在问题中提到它),我需要创建的列表是一个静态字段,我只能将它上传到一个静态初始化程序块中,我无法访问任何 Context 实例。在这种情况下有什么想法吗? :(
  • @iccthedral:因为反射非常昂贵且不安全。 Android 已经有一种方法可以完全按照 OP 的要求进行操作。 OP,您将需要一个上下文。时期。您的示例仅将整数添加到列表中,实际上并未加载任何可绘制对象。如果您真的需要尽早使用它们,则应将它们加载到应用程序的整个应用程序的 onCreate 方法中。也就是说,你的类扩展了Application
【解决方案2】:

你可以试试这个。 YourClassName.class.getFields();

Field[] fields = R.drawable.class.getFields();

您可以迭代所有字段,如果您的字段超出您的需要,您可能需要对其进行过滤。

【讨论】:

    【解决方案3】:

    一种方法是使用反射 API。

    有点意思...

    Field[] fields =  R.drawable.class.getFields();
    List<String> names = new ArrayList<String>(); 
    for (Field field : fields) {
        if(field.getName().startsWith("icon")) 
           names.add(field.getName());    
    }
    
    int resid = getResources().getIdentifier(names.get(0), "drawable", "com.org.bla");
    

    我没有对此进行测试,但你明白了。

    【讨论】:

    • @AljoshaBre 因为反射真的很慢(尤其是在 Dalvik 上)。你可以得到一两个残基。在这种情况下,我们谈论的是 100。如果我没记错的话,getIdentifier() 在内部也使用反射,这并没有让事情变得更好。看看this question 和linked one in it。虽然我会说衡量并做出自己的决定。根据我的经验,这只是听起来是个坏主意。
    • 谢谢!有没有办法在没有 getResources() 函数的情况下做到这一点?我目前无权访问任何上下文,我需要创建此列表。
    • 天啊,Dalvik 的速度慢得令人痛苦。我的错,但是嘿-如果您缓存结果并适当地使用getIdentifier(...),那么这个解决方案应该没问题。但是,无论如何我都会使用 XML。正如 Rahmathullah 所展示的那样。
    【解决方案4】:

    这是我最终做的:

    icons = new ArrayList<Integer>(100);
    
    //get all the fields of the R.drawable class.       
    Field  [] fields = R.drawable.class.getDeclaredFields();
    
    //create a temporary list for the names of the needed variables.
    ArrayList <String> names = new ArrayList<String>(100);
    
    //select only the desired names.
    for(int i=0; i<fields.length; i++)
        if(fields[i].getName().contains("icon_"))
            names.add(fields[i].getName());
    
    //sort these names, because later i want to access them like icons.get(0)
    //what means i want icon_0.
    Collections.sort(names);
    
    try
    {
        for(int i=0; i<names.size(); i++)
        {
            //get the actual value of these fields, 
            //and adding them to the icons list.
            int id = R.drawable.class.getField(names.get(i)).getInt(null);
            icons.add(id);
        }
    }
    catch(Exception ex)
    {
        System.out.println(ex.getMessage());
    }
    

    我敢肯定,这不是最快的方法,但它确实有效。我会接受 AljoshaBre 的解决方案,因为他的回答使我找到了这个解决方案。

    感谢大家的帮助!

    【讨论】:

    • 好吧,好吧;但我希望您了解在 Dalvik 上使用反射 API 的所有利弊。
    • 这是第二次或第三次,我看到了反射 API 的作用,所以我不知道优点/缺点,我什至不知道 Dalvik 是什么意思。我只是不想使用 xml 方法,因为我必须输入与手动将 ID 添加到列表中一样多的内容。那么您能否提供一些关于反射的资料?
    猜你喜欢
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 2015-06-30
    • 2014-12-14
    相关资源
    最近更新 更多