Cómo implementar una galería de imágenes (imágenes locales)

Actualmente estoy haciendo una aplicación para mostrar imágenes de la tarjeta SD. Básicamente usted hace un álbum y agrega cuadros a él, sea de la cámara del selector de MediaStore.

He intentado implementar 2 métodos:

  1. La aplicación de galería estándar con un BaseAdapter personalizado para devolver una vista
  2. Un viewpager con PagerAdapter personalizado

No quiero mostrar una vista de cuadrícula, por lo que debe ir a pantalla completa de inmediato. Después de que quiero deshabilitar deslizar hacia la izquierda y la derecha y sólo escuchar los clics.

Atm ambos métodos funcionan en modo retrato. Cuando cambio al paisaje, algunas imágenes solo se dejan

03-20 12:20:56.515: W/OpenGLRenderer(17398): Bitmap too large to be uploaded into a texture 

Seguido de errores de memoria insuficiente. Desbordamiento de pila si está lleno con problemas sobre el OOM y la galería, debe reciclar las vistas para que funcionen porque convertView siempre es nulo en el getView de BaseAdapter.

Así que utilicé un reciclador para las vistas, lo limito a 2 vistas y el modo de retrato trabajado para el método 1 (usando la galería). El paisaje todavía me da el mismo problema.

Para el método 2 (viewflipper) maneja las vistas por

 @Override public void destroyItem(ViewGroup container, int position, Object object) { 

Lo que nunca se llama btw … Sin embargo, el modo retrato funciona aquí. El paisaje todavía se estrella.

Mi método para obtener el mapa de bits:

 public static Bitmap getBitmap(Context ctx, int imageId, ImageView target) { String file = getPath(ctx, imageId); BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(file, bmOptions); WindowManager mgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); int scaleFactor = 1; if (mgr != null) { // Get the dimensions of the View int targetW = mgr.getDefaultDisplay().getWidth(); int targetH = mgr.getDefaultDisplay().getHeight(); Log.d(TAG, "Image width + height=" + targetW + "," + targetH); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Determine how much to scale down the image scaleFactor = Math.min(photoW / targetW, photoH / targetH); } else { Log.d(TAG, "Target is null"); } // Get the dimensions of the bitmap // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; logHeap(ImageHelper.class); Bitmap bm = BitmapFactory.decodeFile(file, bmOptions); if (target != null) { target.setImageBitmap(bm); } return bm; } 

Funciona bien, sé que uso el gestor de ventanas para obtener un screensize, pero eso es porque mi ImageView sigue siendo el tamaño (0,0) cuando lo inflado. Después llamo

 imgView.setLayoutParams(new Gallery.LayoutParams( Gallery.LayoutParams.FILL_PARENT, Gallery.LayoutParams.FILL_PARENT)); imgView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 

Nada parece funcionar …

Tenga en cuenta que no uso drawables o cualquier otro recurso incluido en el APK. Esta galería debe ser capaz de cargar imágenes de la tarjeta SD o de la cámara en cualquier calidad que fueron tomadas. Obviamente la galería debería ser capaz de manejar tantas imágenes como las que hay en el directorio.

¿Podría alguien por favor ayudarme con las siguientes preguntas?

  1. ¿Hay alguna manera de hacer que la Galería predeterminada vaya a pantalla completa de inmediato y bloquee la vista de cuadrícula? De esta manera sólo necesito un adaptador para proporcionar imágenes en lugar de hacer mis propias vistas. (Tal vez esto resuelve el OOM se bloquea)
  2. ¿Es mi función de decodificación Bitmap ok? ¿Necesito construir algunos hacks para capturar los cambios del paisaje?
  3. ¿Cuál es la mejor manera de hacer el tipo de galería que necesito, usando un viewpager o la galería?
  4. ¿Alguien tiene algún código de ejemplo de una galería de pantalla completa que no se bloquea?

Este es un problema que me he enfrentado a unas pocas veces en el pasado. Google publicó un artículo sobre esto.

El problema está en inSampleSize que usas para decodificar la imagen. Dado que los diferentes dispositivos tienen diferentes pantallas y tamaños de memoria (VM Heap Tamaños que pueden ir de 12 a 64 o más Mb) no se puede decodificar las imágenes de la misma manera en todas ellas. Por ejemplo, una imagen en un dispositivo 320×240 con una memoria Heap de 12Mb debería ser dada enSampleSize mientras que un dispositivo de memoria Heap de 1280×720 64Mb debería usar otro inSampleSize (uno más grande).

El artículo i attack muestra una forma eficiente de renderizar las imágenes para una determinada altura y ancho. Preste especial atención al último segmento de código, "pre-abra" el archivo y calcule el inSampleSize para una "decodificación completa" más adelante.

También quisiera añadir estas recomendaciones.

  1. Utilice la función "getBitmap" de una manera asíncrona, llame a un nuevo subproceso oa un asyncTask (esto se hace porque usar el SD toma tiempo y esto hará que su aplicación se cuelgue, sea lenta y dé una mala impresión en low-mid end Dispositivos.

  2. Intente utilizar siempre el mismo objeto Bitmap. Evite crear múltiples "Bitmap bitmap = new Bitmap ()". Tienes que darse cuenta de que los mapas de bits cargados se almacenan en RAM y una vez asignado a una vista de su "más difícil" para que el recolector de basura para obtenerlos.

  3. Cuando haya terminado de usar un mapa de bits, haga que sea nulo. Esto de esto, imagina que tienes 12 MB de memoria RAM de montón. Su aplicación está usando 8Mb ahora. El recolector de basura empieza y no puede obtener más RAM sin usar. 10 Bitmaps rápidos nunca los hacen nulos después de asignar los datos al ImageView y de alguna manera conservan su referencia. Tomado que cada mapa de bits tomar 500Kb de Ram su aplicación se bloqueará. Haga siempre Bitmaps nulos después de usar.

  4. Por último, utilice el DDMS proporcionado en las herramientas de plataforma de Google (puede acceder a él con el eclipse para depurar y ver el uso de memoria, también puede forzar a Garbage Collection a ver cómo se comporta su aplicación).

  • Cómo corregir este error: java.lang.OutOfMemoryError
  • Volley me da fuera de la excepción de memoria después de hacer un montón de solicitud con gran cantidad de datos
  • Android sin memoria en la captura de imágenes
  • Excepción OutOfMemory en la conversión de ByteArray a String?
  • Java.lang.OutOfMemoryError en Android 5.0, causado por una asignación de 16k cuando 5M está disponible
  • Android cómo mantener una lista grande <String > mientras se ejecuta la aplicación
  • Detectando OutOfMemoryError en la decodificación Bitmap
  • Fuera de error de memoria en android debido al aumento de tamaño de montón
  • Propósito de los parámetros XXMaxPermSize, vmargs, Xms y Xms en eclipse.ini, ¿qué hacen
  • Problemas de memoria en fragmentos que muestran imágenes
  • ¿Cifrado de archivos de vídeo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.