9

我想从存储在 res/drawable 中的一堆图像中显示一个随机图像。

我知道的唯一技术是访问特定图像,如果你知道它的资源 id。有没有办法通过使用文件名或其他东西(可以在运行时构建)来访问图像?

我想在运行时随机选择一个图像。任何建议/想法表示赞赏:)

谢谢钦梅

4

8 回答 8

21

我意识到这是一个非常古老的问题,但想为任何 Google 员工提供一个好的解决方案。

按名称访问资源的效率远低于按 ID。资源系统的全部意义在于您不必解析名称,而是可以使用 ids。

您需要做的是利用Array Resource类型。跟着我的简单步骤!我制作随机图像...有趣!

  1. 创建一个数组资源,其中包含您要从中选择的所有图像。我把它放在我的res/values/arrays.xml文件中,但它真的可以去任何地方。

    <array name="loading_images">
        <item>@drawable/bg_loading_1</item>
        <item>@drawable/bg_loading_2</item>
        <item>@drawable/bg_loading_3</item>
        <item>@drawable/bg_loading_5</item>
        <item>@drawable/bg_loading_6</item>
        <item>@drawable/bg_loading_7</item>
        <item>@drawable/bg_loading_8</item>
    </array>
    
  2. 接下来,TypedArray从 中获取Resources并使用它来选择随机图像。

    TypedArray images = getResources().obtainTypedArray(R.array.loading_images);
    int choice = (int) (Math.random() * images.length());
    mImageView.setImageResource(images.getResourceId(choice, R.drawable.bg_loading_1));
    images.recycle();
    
  3. 利润!

于 2014-01-07T15:39:11.347 回答
6

您还可以按名称访问资源,如果您知道资源的名称或可以根据某些预定义的命名方案派生它们,这可能是解决问题的可行方法。

您必须使用类的getIdentifier方法将名称映射到标识符Resources

String name = "resource" + rng.nextInt(count);
int resource = getResources().getIdentifier(name, "drawable", "com.package");

此方法的文档说:

注意:不鼓励使用此功能。按标识符检索资源比按名称检索资源效率更高。

这是真的,但如果您在对性能不敏感的代码中执行此操作,则不必成为问题。

或者,如果您不介意在 XML 中列出资源,您可以创建一个类型化数组,然后可以从中随机选择。

于 2010-08-16T23:16:57.593 回答
2

res/drawable 中的项目在编译时在 R.drawable 类中枚举。您可能可以使用反射来获取该类成员的列表,然后从该列表中随机选择。

于 2010-08-16T20:39:57.240 回答
1

我想不出你在运行时可以做的任何事情。您可以创建一个地址整数数组(因为R.drawable.xxxx本质上是一个整数地址),然后用于java.util.Random从您的数组中选择一个随机资源地址。

于 2010-08-16T20:38:20.387 回答
0

如果您不介意设置<level-list>XML 文件,您应该能够使用 aLevelListDrawablesetImageLevel()使用您的随机数调用。

如果您不想在添加文件时更改此列表,我会假设有某种方法可以设置构建事件,您可以在其中以编程方式生成此文件。

于 2010-08-16T20:50:53.570 回答
0

我在 Applez 应用程序中执行以下操作;

1)创建一个 ArrayList 来保存图像并填充它 2)取随机数并返回相应的图像。

在代码中:

public static void fruitInventory() {
fruitResources.clear();
Field[] fields = R.drawable.class.getFields();

for (Field field : fields) {
    // Take only those with name starting with "fr"
    if (field.getName().startsWith("fr_")) {
        try {
            String FType = field.getName().substring(3);

            fruitResources.add(field.getInt(null));
            alfruitTypes.add(FType);
            Log.d("FruitManager", "Type " + FType);

        } catch (IllegalArgumentException e) {

            e.printStackTrace();
        } catch (IllegalAccessException e) {

            e.printStackTrace();
        }
    }


}

并添加水果:

public static void addFruit(Context context){

fruitInventory();

for (int i = 0; i < 10; i++) {
Random Rnd = new Random();
int FruitType = Rnd.nextInt(fruitResources.size());
GameObject nextApple = new GameObject(BitmapFactory.decodeResource(context.getResources(),
                  fruitResources.get(FruitType)), FruitType);

MainGamePanel.AppleList.add(nextApple);
}

}

想法是(并且有效)我可以在游戏中添加额外的水果,只需将“fr_eggplant.bmp”添加到图像文件夹即可。

于 2013-02-09T19:59:17.763 回答
0

我从未使用过 AssetManager,但是您能否在资源类上调用 getAssets,然后在 AssetManager 上调用 list 以及资源的位置?

于 2010-08-16T20:43:56.577 回答
0

如果你知道你有 X 个图像可供选择,可以使用 random.nextInt(X) 随机生成一个介于 0(包括)和 X(不包括)之间的整数,然后打开它来选择你的资源:

Random mRand = new Random();
            int x = mRand.nextInt(8);
            switch (x) {
            case 0:
                mResource = R.id.someresource1
            case 1:
                mResource = R.id.someresource2
            ...
            case X:
                mResource = R.id.someresourceX

            }
于 2010-08-16T20:41:09.250 回答