ImageView adjustViewBounds no funciona

Tengo un ImageView con android:layout_width=100dp , android:layout_height=wrap_content y android:adjustViewBounds=true

Su fuente es una imagen de 50 x 50 px. Pero la relación de aspecto no se conserva – la altura del ImageView es 50px, no 100px (es decir, adjustViewBounds no está funcionando). Si tengo una imagen de 200x200px funciona – el ancho y la altura son 100px. Este código da como resultado una imagen de 100px de ancho y 50px de altura, pero la imagen de src es cuadrada:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/photo" android:src="@drawable/icon" android:layout_width="100dp" android:layout_height="wrap_content" android:scaleType="fitXY" android:adjustViewBounds="true" /> </LinearLayout> 

El problema es que adjustViewBounds no aumentará el tamaño del ImageView más allá de las dimensiones naturales del dibujable. Sólo reducirá la vista para mantener la relación de aspecto; Si proporciona una imagen 500×500 en lugar de una imagen 50×50, esto debería funcionar.

Si está interesado en el lugar donde se implementa este comportamiento, consulte la implementación de onMeasure de ImageView.java .

Una solución es implementar un ImageView personalizado que cambia este comportamiento en onMeasure .

Hay una manera más simple. Haga su ImageView como esto:

 <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:adjustViewBounds="true"/> 

De esta forma, se puede estirar para encajar en el centro ImageView preservando la relación de aspecto. Sólo tenemos que calcular la altura correcta para que sea proporcional, así que no tenemos ningún espacio en blanco:

 private void setImageBitmap(Bitmap bitmap, ImageView imageView){ float i = ((float)imageWidth)/((float)bitmap.getWidth()); float imageHeight = i * (bitmap.getHeight()); imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidth, (int) imageHeight)); imageView.setImageBitmap(bitmap); } 

Yo tenía un requisito similar; En mi caso, quería que la imagen fuera cuadrada, y quería que ImageView coincidiera con la relación de aspecto para poder usar su fondo y relleno para dibujar un borde.

He leído las respuestas aquí, pero en lugar de reemplazar ImageView, decidí hacer un Layout que garantiza su contenido (debe ser sólo una vista) son cuadrados. De esa manera podría usar un ImageView estándar dentro de él. (Y nunca se sabe, tal vez quiera hacer algo más cuadrado más tarde, aunque probablemente no.)

En caso de que sea útil para cualquier otra persona, aquí está el código (no dude en copiar). Probablemente hay bugs como lo hice funcionar para mi aplicación y luego se detuvo. 🙂

 public class SquareLayout extends ViewGroup { public SquareLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SquareLayout(Context context, AttributeSet attrs) { super(context, attrs); } public SquareLayout(Context context) { super(context); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // Work out width and height, and square size. int width = r - l; int height = b - t; int size, xOffset, yOffset; if(width < height) { size = width; xOffset = 0; yOffset = (height - size) / 2; } else { size = height; xOffset = (width - size) / 2; yOffset = 0; } for(int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.layout(xOffset, yOffset, size + xOffset, size + yOffset); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Get width and height. int w = -1, h = -1; switch(MeasureSpec.getMode(widthMeasureSpec)) { case MeasureSpec.AT_MOST: case MeasureSpec.EXACTLY: w = MeasureSpec.getSize(widthMeasureSpec); break; case MeasureSpec.UNSPECIFIED: break; } switch(MeasureSpec.getMode(heightMeasureSpec)) { case MeasureSpec.AT_MOST: case MeasureSpec.EXACTLY: h = MeasureSpec.getSize(heightMeasureSpec); break; case MeasureSpec.UNSPECIFIED: break; } // If only one of width/height is unspecified, set them both the same. if(w == -1 && h != -1) { w = h; } else if(h == -1 && w != -1) { h = w; } // Either they're both specified or both unspecified. int childMeasureSpec; if(w == -1) { childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else { childMeasureSpec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY); } // Pass through to children. int maxDimension = 1; for(int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(childMeasureSpec, childMeasureSpec); maxDimension = Math.max(maxDimension, child.getMeasuredWidth()); maxDimension = Math.max(maxDimension, child.getMeasuredHeight()); } if(w == -1) { w = maxDimension; h = maxDimension; } setMeasuredDimension(w, h); } } 

Además de la respuesta @ RomanNurik

Puede encontrar una solución de trabajo aquí , ya sea copiar o pegar código o simplemente añadir la dependencia de Gradle

 dependencies { compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.1' } 

PS Solución proporcionada por @Nilzor no funcionó para mí

  • Cómo crear una imagen de perfil circular de facebook
  • Obtener coordenadas reales de xy de los usuarios
  • La ondulación se dibuja a continuación ImageView
  • Android ImageView sombra de la gota
  • Cambiar el tamaño de ImageView en tiempo de ejecución mediante un botón - Android
  • Android: ¿Generar color aleatorio al hacer clic?
  • Adición de Fling Gesture a una vista de imagen - Android
  • BaseAdapter y ContextMenu
  • Cómo cargar un mapa de bits con Picasso sin usar un ImageView?
  • Android se desvanece y se desvanece con ImageView
  • Cargar imagen en ImageView de la URL almacenada en JSONString en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.