Escala de imagen manteniendo su relación de aspecto en fondo dibujable

¿Cómo puedo hacer que una imagen de fondo se ajuste a la vista, pero mantener su relación de aspecto cuando se utiliza <bitmap /> como un fondo xml dibujable? Ninguno de los valores de android:gravity de <bitmap> da el efecto deseado.

Es imposible lograr el atributo de fondo de manipulación dentro de archivos xml solamente. Hay dos opciones:

  1. Puede cortar / escalar el mapa de bits mediante programación con Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) y configurarlo como el fondo de View .

  2. Utiliza ImageView lugar de fondo colocándolo como elemento del primer diseño y especifica el atributo android:scaleType para él:

     <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/backgrnd" android:scaleType="centerCrop" /> ... rest layout components here ... </RelativeLayout> 

Hay una manera fácil de hacer esto del drawable:

Your_drawable.xml

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@color/bg_color"/> <item> <bitmap android:gravity="center|bottom|clip_vertical" android:src="@drawable/your_image" /> </item> </layer-list> 

El único inconveniente es que si no hay suficiente espacio, su imagen no se mostrará completamente, pero se cortará, no pude encontrar una manera de hacerlo directamente desde un dibujable. Pero a partir de las pruebas que hice que funciona bastante bien, y no clip que gran parte de la imagen. Podrías jugar más con las opciones de gravedad.

Otra forma será simplemente crear un diseño, donde se utilizará un ImageView y establecer el scaleType para fitCenter .

Esperamos que esta información le ayude a lograr lo que quiere.

Otro enfoque sería crear imágenes de patch 9 de su imagen normal y hacer que la escala de estiramiento de la manera que desee.

Usted podría tener que centrar el contenido mediante la colocación de 9 puntos de parche en las esquinas que conservarán su relación obviamente (suponiendo que el borde exterior más de su imagen es repetible / transparente).

Esperamos que tengas la idea.

El uso del método descrito por a.ch funcionó muy bien para mí, excepto que he utilizado este tipo de escala que funcionó mucho mejor para lo que necesitaba:

 android:scaleType="centerCrop" 

Aquí hay una lista completa de tipos de escala disponibles: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

Intenta usar InsetDrawable (funcionó bien para mí).

Apenas dé esto su drawable, e inserciones (o el relleno) que usted quiere de cualquiera de los cuatro lados.

 InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom); 

Se utiliza específicamente para establecer el fondo dibujable, de tamaño más pequeño o que la vista.

Vea aquí: https://developer.android.com/reference/android/graphics/drawable/InsetDrawable.html

La vieja pregunta, pero ninguna de las otras respuestas funcionó para mí. Este código xml hizo sin embargo:

 <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:scaleType="centerCrop" android:src="@drawable/background_image"/> </RelativeLayout> 

Si su mapa de bits es más ancho que alto, utilice android:gravity="fill_vertical" . De lo contrario, use android:gravity="fill_horitzonal" . Esto tiene un efecto similar al uso de android:scaleType="centerCrop" en un ImageView .

 <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill_vertical" android:src="@drawable/image" /> 

Si admite varias orientaciones, puede crear un archivo XML de mapa de bits en la carpeta de drawable-port dibujable y el otro en la carpeta de drawable-land dibujo.

Quería hacer algo similar en mi clase Drawable personalizada. Aquí están las piezas importantes:

 public class CustomBackgroundDrawable extends Drawable { private Rect mTempRect = new Rect(); private Paint mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); ... public void draw(@NonNull Canvas canvas) { Rect bounds = getBounds(); if (mBitmap != null ) { if (mScaleType == ScaleType.SCALE_FILL) { //bitmap scales to fill the whole bounds area (bitmap can be cropped) if (bounds.height() > 0 && bounds.height() > 0) { float scale = Math.min(mBitmap.getWidth()/(float)bounds.width(), mBitmap.getHeight()/(float)bounds.height()); float bitmapVisibleWidth = scale * bounds.width(); float bitmapVisibleHeight = scale * bounds.height(); mTempRect.set((int)(mBitmap.getWidth()-bitmapVisibleWidth)/2, 0, (int)(bitmapVisibleWidth+mBitmap.getWidth())/2, (int)bitmapVisibleHeight); canvas.drawBitmap(mBitmap, mTempRect, bounds, mBitmapPaint); } } else if (mScaleType == ScaleType.SCALE_FIT) { //bitmap scales to fit in bounds area if (bounds.height() > 0 && bounds.height() > 0) { float scale = Math.min((float)bounds.width()/mBitmap.getWidth(), (float)bounds.height()/mBitmap.getHeight()); float bitmapScaledWidth = scale * mBitmap.getWidth(); float bitmapScaledHeight = scale * mBitmap.getHeight(); int centerPadding = (int)(bounds.width()-bitmapScaledWidth)/2; mTempRect.set(bounds.left + centerPadding, bounds.top, bounds.right - centerPadding, bounds.top+(int)bitmapScaledHeight); canvas.drawBitmap(mBitmap, null, mTempRect, mBitmapPaint); } } } } 

Con este enfoque usted es flexible para aplicar cualquier lógica de escala que necesite

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.