2010-08-16 12 views
6

Quiero mostrar una imagen aleatoria del conjunto de imágenes que he almacenado en res/dibujable.cómo seleccionar recursos aleatoriamente (R.drawable.xxxx)

La única técnica que conozco es acceder a una imagen en particular si conoce su id de recurso. ¿Hay alguna manera de acceder a las imágenes usando los nombres de los archivos u otra cosa (que se puede construir en tiempo de ejecución)?

Quiero seleccionar aleatoriamente una imagen en tiempo de ejecución. Cualquier sugerencia/ideas apreciados :)

Gracias Chinmay

Respuesta

3

También puede acceder a los recursos por su nombre, lo que puede ser un enfoque viable para resolver su problema si conoce los nombres de los recursos o puede derivarlos según un esquema de nombres predefinido.

Debe asignar el nombre al identificador utilizando el método getIdentifier de la clase Resources.

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

La documentación de este método dice:

Nota: El uso de esta función es desanime. Es mucho más eficiente para recuperar recursos con el identificador que por su nombre.

Esto es cierto pero no es necesario que sea un problema si lo hace en un código que no es sensible al rendimiento.

Alternativamente, si no le importa enumerar los recursos en XML, puede crear a typed array que luego puede seleccionar al azar.

1

No puedo pensar en nada se puede hacer en tiempo de ejecución. Posiblemente podría crear una matriz de enteros de direcciones (ya que el R.drawable.xxxx es esencialmente una dirección entera) y luego usar java.util.Random para seleccionar una dirección de recurso aleatoria de su matriz.

+0

Pensé en esto ... pero no quiero cambiar el código cada vez que agrego algunas imágenes a mi directorio de res /. –

+0

Creo que Mayra tiene la respuesta. – bporter

2

Los elementos en res/dibujables se enumeran en la clase R.drawable en tiempo de compilación. Probablemente pueda usar reflection para obtener una lista de los miembros de esa clase, y luego seleccionar de esa lista al azar.

+1

Acabo de probar esto y pude obtener una lista de nombres de recursos, solo se necesitaría un paso más para devolver su valor. Pude ver que la reflexión funcionó. Gran sugerencia Mayra! Aquí está la línea de código para obtener los nombres de los campos: java.lang.reflect.Field [] fields = R.drawable.class.getFields(); – bporter

0

Si sabía que tenía imágenes X para elegir podría utilizar random.nextInt (X) para generar aleatoriamente un número entero entre 0 (ambos inclusive) y X (exclusivo), y luego cambiar en él para recoger su recurso:

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 

      } 
+0

Esta es esencialmente una forma más complicada de hacer lo que sugirió bporter, recomendaría usar ese método en su lugar, es más ordenado. – QRohlf

0

Nunca he usado AssetManager, pero ¿podría llamar a getAssets en su clase Resources, y luego llamar a la lista en AssetManager con la ubicación de sus recursos?

0

Si no le importa configurar un archivo XML <level-list>, debe poder usar un LevelListDrawable y llamar al setImageLevel() con su número aleatorio.

Si no desea cambiar esta lista cuando agrega archivos, supongo que hay alguna forma de configurar un evento de compilación donde podría generar progmáticamente este archivo.

0

Lo hice en mi aplicación Applez de la siguiente manera;

1) crear una ArrayList para contener imágenes y completarla 2) tomar un número aleatorio y devolver la imagen correspondiente.

en código:

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(); 
     } 
    } 


} 

y añadir la fruta:

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); 
} 

}

idea era (y trabaja) que podría agregar frutas adicionales para el juego, simplemente agregando por ejemplo "fr_eggplant.bmp" a la carpeta de imágenes.

12

Me doy cuenta de que esta es una vieja pregunta, pero quería proporcionar una buena solución para cualquier Googlers.

Los recursos de acceso por nombre son mucho menos eficientes que por id. El objetivo del sistema de recursos es que no tenga que resolver nombres, y puede usar identificadores en su lugar.

Lo que necesita hacer es utilizar el tipo Array Resource. Siga junto con mis pasos sencillos! Hago imágenes aleatorias ... ¡Diversión!

  1. Cree un recurso de matriz que incluya todas las imágenes que desee elegir. Puse esto en mi archivo res/values/arrays.xml, pero realmente puede ir a cualquier parte.

    <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. A continuación, obtener el TypedArray del Resources y el uso que elegir una imagen aleatoria.

    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. Profit!

Cuestiones relacionadas