Escalar la imagen manteniendo su relación de aspecto en el fondo dibujable
¿Cómo hago que una imagen de fondo se ajuste a la vista pero mantenga su relación de aspecto cuando uso <bitmap />
como XML de elemento de diseño de fondo?
Ninguno de los valores de <bitmap>
da el efecto deseado.
9 answers
Es imposible lograr manipular el atributo background solo dentro de los archivos xml. Hay dos opciones:
Puede cortar / escalar el mapa de bits mediante programación con
Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
y ponlo como fondo de algúnView
.-
Se usa
ImageView
en lugar de background colocándolo como el primer elemento del layout y especificandoandroid:scaleType
atributo para ello:<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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-05 08:34:28
Hay una manera fácil de hacer esto desde el elemento de diseño:
Su_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 recortará, no pude encontrar una manera de hacer esto directamente desde un elemento de diseño. Pero de las pruebas que hice funciona bastante bien, y no corta mucho de la imagen. Podrías jugar más con las opciones de gravedad.
Otra forma será simplemente crear un diseño, donde se utilice un ImageView
y establecer el scaleType
to fitCenter
.
Espero que esta información le ayude a lograr lo que desea.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-21 09:05:47
Otro enfoque sería crear imágenes de parche 9 de su imagen normal y hacerla estirar la escala de la manera que desee.
Puede hacer que centre el contenido poniendo 9 puntos de parche en las esquinas que preservarán su relación obviamente (suponiendo que el borde más exterior de su imagen sea repetible/transparente).
Espero que tengas la idea.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 20:49:52
Quería hacer algo similar en mi clase de elementos de diseño personalizados. 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 eres flexible para aplicar cualquier lógica de escala que necesites
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-23 12:54:33
Utilizando el método descrito por a.ch funcionó muy bien para mí, excepto que usé este tipo de escala que funcionó mucho mejor para lo que necesitaba:
android:scaleType="centerCrop"
Aquí está una lista completa de los tipos de escala disponibles: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-12 17:02:30
Intente usar InsetDrawable (funcionó bien para mí).
Simplemente dale a este tu elemento de diseño, y las inserciones (o relleno) que quieras de cualquiera de los cuatro lados.
InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom);
Se usa específicamente para configurar el elemento de diseño de fondo, de tamaño más pequeño o que la vista.
Ver Aquí : https://developer.android.com/reference/android/graphics/drawable/InsetDrawable.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-13 08:51:29
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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-07 15:24:41
Si su mapa de bits es más ancho que alto, use android:gravity="fill_vertical"
. De lo contrario, utilice android:gravity="fill_horizontal"
. 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 drawable-port
y el otro en la carpeta drawable-land
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-15 02:28:58
Para ajustar la imagen al espacio disponible (o si ha establecido ancho y alto en dp), he probado este enfoque si la imagen no es demasiado ancha.
Aquí he establecido el mismo ancho y alto para las imágenes cuadradas [o puede wrap_content en ambos].
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/background_image"/>
</RelativeLayout>
Ajustar los límites de la vista y el ajuste central del tipo de escala hacen el truco.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 04:56:52