【问题标题】:how to select from resources randomly (R.drawable.xxxx)如何从资源中随机选择(R.drawable.xxxx)
【发布时间】:2026-02-13 23:15:01
【问题描述】:

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

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

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

谢谢 钦梅

【问题讨论】:

    标签: android android-image


    【解决方案1】:

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

    按名称访问资源的效率远低于按 ID。资源系统的重点是让您不必解析名称,而是可以使用 id。

    您需要做的是使用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. 接下来,从Resources 中获取TypedArray 并使用它来选择随机图像。

      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. 利润!

    【讨论】:

      【解决方案2】:

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

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

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

      这个方法的文档说:

      注意:这个函数的使用是 灰心。它效率更高 按标识符检索资源 比名字。

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

      或者,如果您不介意在 XML 中列出资源,您可以创建 a typed array,然后您可以从中随机选择。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 我刚刚尝试过,并且能够获得资源名称列表 - 只需再执行一个步骤即可返回它们的值。我能够看到反射起作用。伟大的建议梅拉!这是获取字段名称的代码行:java.lang.reflect.Field[] fields = R.drawable.class.getFields();
        【解决方案4】:

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

        【讨论】:

        • 我确实想到了这个......但我不想每次在我的 res/ 目录中添加一些图像时都更改代码。
        • 我相信 Mayra 有答案。
        【解决方案5】:

        如果您知道您有 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
        
                    }
        

        【讨论】:

        • 这本质上是一种更复杂的方式来执行 bporter 建议的操作,我建议改用该方法,它更整洁。
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          如果您不介意设置&lt;level-list&gt; XML 文件,您应该可以使用@987654321@ 并使用您的随机数调用@987654322@

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

          【讨论】:

            【解决方案8】:

            我在 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”添加到图像文件夹即可。

            【讨论】: