我想从存储在 res/drawable 中的一堆图像中显示一个随机图像。
我知道的唯一技术是访问特定图像,如果你知道它的资源 id。有没有办法通过使用文件名或其他东西(可以在运行时构建)来访问图像?
我想在运行时随机选择一个图像。任何建议/想法表示赞赏:)
谢谢钦梅
我想从存储在 res/drawable 中的一堆图像中显示一个随机图像。
我知道的唯一技术是访问特定图像,如果你知道它的资源 id。有没有办法通过使用文件名或其他东西(可以在运行时构建)来访问图像?
我想在运行时随机选择一个图像。任何建议/想法表示赞赏:)
谢谢钦梅
我意识到这是一个非常古老的问题,但想为任何 Google 员工提供一个好的解决方案。
按名称访问资源的效率远低于按 ID。资源系统的全部意义在于您不必解析名称,而是可以使用 ids。
您需要做的是利用Array Resource类型。跟着我的简单步骤!我制作随机图像...有趣!
创建一个数组资源,其中包含您要从中选择的所有图像。我把它放在我的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>
接下来,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();
利润!
您还可以按名称访问资源,如果您知道资源的名称或可以根据某些预定义的命名方案派生它们,这可能是解决问题的可行方法。
您必须使用类的getIdentifier方法将名称映射到标识符Resources
。
String name = "resource" + rng.nextInt(count);
int resource = getResources().getIdentifier(name, "drawable", "com.package");
此方法的文档说:
注意:不鼓励使用此功能。按标识符检索资源比按名称检索资源效率更高。
这是真的,但如果您在对性能不敏感的代码中执行此操作,则不必成为问题。
或者,如果您不介意在 XML 中列出资源,您可以创建一个类型化数组,然后可以从中随机选择。
res/drawable 中的项目在编译时在 R.drawable 类中枚举。您可能可以使用反射来获取该类成员的列表,然后从该列表中随机选择。
我想不出你在运行时可以做的任何事情。您可以创建一个地址整数数组(因为R.drawable.xxxx
本质上是一个整数地址),然后用于java.util.Random
从您的数组中选择一个随机资源地址。
如果您不介意设置<level-list>
XML 文件,您应该能够使用 aLevelListDrawable
并setImageLevel()
使用您的随机数调用。
如果您不想在添加文件时更改此列表,我会假设有某种方法可以设置构建事件,您可以在其中以编程方式生成此文件。
我在 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”添加到图像文件夹即可。
我从未使用过 AssetManager,但是您能否在资源类上调用 getAssets,然后在 AssetManager 上调用 list 以及资源的位置?
如果你知道你有 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
}