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" /> 
  • Recuperar la imagen de mysql-php (android)
  • Dibujo de una cabeza de flecha en android
  • ¿Cuál es el significado de la palabra ImageView.ScaleType = "MATRIX"?
  • Android y la configuración de alfa para (imagen) ver alfa
  • Android: Cargar imagen desde la URL web
  • El brillo de una imagen sigue aumentando incluso al mover la barra de desplazamiento de Seekbar a la izquierda
  • Android ImageView no coincide con_parent dentro de FrameLayout por debajo de GingerBread
  • Cómo guardar la imagen en la galería de Android
  • Cómo configurar el efecto de brillo exterior en ImageView?
  • La imagen no se ajusta automáticamente
  • Android - Crossfade mutiple imágenes en un ImageView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.