La dimensión de la pantalla del dispositivo tiene un efecto extraño en las imágenes a escala

Actualización: Las dimensiones de pantalla del dispositivo múltiple es un arenque rojo – el problema es que la imagen no se amplía correctamente para llenar la pantalla – ver comentarios sobre la respuesta de Iván.

Tengo un archivo de diseño con una imagen:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/image" android:layout_width="fill_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="centerCrop" /> 

Entonces asigno un dibujable, que es pequeño y debe ser ampliado:

 setContentView(R.layout.image_story); ImageView image = (ImageView)findViewById(R.id.image); image.setImageDrawable(s.image); 

Aquí es cómo se representa en dos AVD con diferentes dimensiones de pantalla. Estos deben ser los mismos (pregunta detallada en la parte inferior). Lo siento por las imágenes grandes.

Con scaleType = centerCrop:

Con centerInside

AVDs:

Editar:

Con layout_height = "fill_parent" y scaleType = "centerInside"

Tengo un 2,1 AVD con los valores por defecto, por lo que la pantalla es más pequeña, y esto funciona exactamente como se espera, la imagen se amplía para llenar el ancho, y la altura de la vista se envuelve a la altura escalada.

En mi Droid Bionic con una pantalla más larga, y en cualquier AVD con las mismas dimensiones de pantalla, esto no funciona: la imagen se escala para llenar el ancho, pero la vista se envuelve a la altura original de la imagen antes de la escala. Arriba y abajo se recortan.

No tengo ni idea de por qué la relación de aspecto de la pantalla del dispositivo tendría un efecto en esto. He intentado innumerables combinaciones de parámetros de diseño y tipos de escala tratando de conseguir que esto funcione en el Bionic. Todo funciona exactamente como se esperaba en la pantalla más pequeña, y no en la más grande. Si configuro la altura de la imagen explícitamente en dp , funciona como esperaba, pero nunca sé cuáles serán las dimensiones de la imagen (o pantalla). ¿Alguna sugerencia?

Esa es una muy buena pregunta.

Esta es la razón por la que se está comportando así (de ImageView.onMeasure (int, int) [línea 661] ):

 // Try adjusting height to be proportional to width if (!done && resizeHeight) { int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) + ptop + pbottom; if (newHeight <= heightSize) { // line 661 heightSize = newHeight; } // line 663 } 

Lo que hace es ajustar la altura de la vista sólo si la nueva altura que se basa en la relación de aspecto de la anchura dibujable y ajustada (en nuestro caso, que es el ancho exacto de la vista principal) es menor que la altura ajustada (que En este punto es sólo la altura nativa drawable más el relleno en nuestro caso. Déjeme saber si usted quiere que frene abajo este punto más lejos.)

Lo que no entiendo es por qué existe la restricción de que la nueva altura debe ser menor. Tiene sentido sólo si nuestro heightSize es EXATAMENTE o AT_MOST y se ha establecido en el límite superior. En otros casos no es necesario que sea así.

En realidad, en lugar de toda la pieza 661 a 663 debería haber habido otra llamada a

 heightSize = resolveAdjustedSize(newHeight, mMaxHeight, heightSpec); 

Para asegurarnos de que sólo usamos la restricción de altura cuando se debe restringir (es decir, tenemos AT_MOST restricción en heightSpec y el valor de altura en heightSpec es menor que la nueva altura. EXACTAMENTE no puede suceder aquí a menos que utilicemos anchura variable).

Tal vez, me perdí algo allí. Chicos, cualquiera que esté leyendo esto, por favor comente si usted ve cualquier defecto en eso, especialmente si usted es parte del equipo de Android en Google 🙂

PS Como una solución, puedo sugerir que implementar un personalizado ImageView y anular onMeasure (int, int) para establecer los límites a su relación de aspecto exacta. Déjeme saber si usted necesita ayuda en el código real.

UPD Voy a escribir los nombres para llamar la atención de los chicos inteligentes android en Google (espero que los chicos tienen alertas de Google creado): Romain Guy, Roman Nurik, Reto Meier, por favor, eche un vistazo a esta discusión.

Como tengo entendido, es necesario escalar la imagen manteniendo su relación de aspecto. scaleType="fitCenter" debería darle el comportamiento deseado:

 <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/image" android:layout_width="fill_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitCenter" /> 

Si no ayuda, intenta agregar esto al archivo de manifiesto:

 <supports-screens android:resizeable="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" /> 
  • ¿Cómo puedo obtener el mapa de bits en caché que he descargado con Volley ImageLoader?
  • Cómo obtener la imagen de url sitio web en imageview en android
  • ¿Cómo subir la imagen a Parse en android?
  • Saltar ImageView mientras arrastra. Los valores de getX () y getY () saltan
  • Despliegue y alineación de la distribución relativa de Android
  • Obtenga la imagen del recurso por nombre en el adaptador de cursor personalizado
  • Eliminar redimensionamiento automático de ImageView
  • Diapositiva personalizada para desbloquear
  • Cómo parpadeo de la imagen en ImageView (Android)
  • Cómo guardar la imagen en la galería de Android
  • La altura de gridView es demasiado alta cuando se utiliza una imagen
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.