android - sociales - Imagen de escala manteniendo su relación de aspecto en fondo dibujable
tamaño de video para facebook 2018 (9)
¿Cómo puedo hacer que una imagen de fondo se ajuste a la vista, pero mantener su relación de aspecto cuando utilizo <bitmap />
como un XML dibujable en segundo plano? Ninguno de <bitmap>
''s android:gravity
valores de android:gravity
dan el efecto deseado.
Es imposible lograr manipular el atributo de fondo solo dentro de los archivos xml. Hay dos opciones:
Corta / escala el mapa de bits mediante programación con
Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
y lo establece como el fondo de unaView
.Utiliza
ImageView
lugar de fondo colocándolo como el primer elemento del diseño y especifica el atributoandroid: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 desde el dibujable:
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 recortará, no pude encontrar una manera de hacerlo directamente desde un dibujante. Pero de las pruebas que hice funciona bastante bien, y no recorta gran parte de la imagen. Podrías jugar más con las opciones de gravedad.
Otra forma será simplemente crear un diseño, donde usará un ImageView
y establecerá el scaleType
en fitCenter
.
Espero que esta información te ayude a lograr lo que quieres.
Intenta usar InsetDrawable (funcionó bien para mí).
Solo déle a este su dibujo y las inserciones (o relleno) que desee de cualquiera de los cuatro lados.
InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom);
Se utiliza específicamente para establecer 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
Otro enfoque sería crear imágenes del parche 9 de su imagen normal y hacer que se estire la escala de la forma que desee.
Puede hacer que centre el contenido colocando 9 puntos de parche en las esquinas que conservarán su relación, obviamente (suponiendo que el borde exterior de su imagen sea repetible / transparente).
Con suerte se entiende la idea.
Para ajustar la imagen al espacio disponible (o si ha configurado el ancho y alto en dp), he intentado este enfoque si la imagen no es demasiado ancha.
Aquí he establecido el mismo ancho y alto para imágenes cuadradas [o puede wrap_content en ambas].
<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 vista y el ajuste de centro de tipo de escala hacen el truco.
Quería hacer algo similar en mi clase Drawable personalizada. Estas son 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, es flexible para aplicar cualquier lógica de escala que necesite
Si su bitmap es más ancho que alto, use android:gravity="fill_vertical"
. De lo contrario, usa android:gravity="fill_horizontal"
. Esto tiene un efecto similar al de usar 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 múltiples 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
dibujable.
Una 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>
Usar el método descrito por a.ch funcionó muy bien para mí, excepto que utilicé este tipo de báscula que funcionaba mucho mejor para lo que necesitaba:
android:scaleType="centerCrop"
Aquí hay una lista completa de los tipos de báscula disponibles: ScaleType