Comment adapter une image d'arrière-plan à la vue tout en conservant ses proportions lorsque vous utilisez <bitmap />
Comme fichier XML pouvant être dessiné en arrière-plan? Aucune des valeurs <bitmap>
De Android:gravity
Ne donne l'effet désiré.
Il est impossible de manipuler l'attribut d'arrière-plan dans les fichiers xml uniquement. Il y a deux options:
Vous coupez/redimensionnez le bitmap par programme avec Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
et vous le définissez comme arrière-plan de View
.
Vous utilisez ImageView
au lieu de l’arrière-plan, vous le placez comme élément de la première mise en page et vous spécifiez Android:scaleType
attribut pour cela:
<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>
Il existe un moyen facile de faire cela depuis le dessinable:
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>
Le seul inconvénient est que s'il n'y a pas assez d'espace, votre image ne sera pas entièrement affichée, mais elle sera coupée, je ne pouvais pas trouver un moyen de le faire directement à partir d'un dessinable. Mais d'après les tests que j'ai effectués, cela fonctionne assez bien et ne coupe pas beaucoup l'image. Vous pourriez jouer plus avec les options de gravité.
Une autre façon de créer une mise en page consiste à utiliser un ImageView
et à définir le scaleType
à fitCenter
.
J'espère que cette information vous aidera à réaliser ce que vous voulez.
Je voulais faire quelque chose de similaire dans ma classe Drawable personnalisée. Voici les pièces 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);
}
}
}
}
Avec cette approche, vous êtes flexible pour appliquer toute logique de balance dont vous avez besoin.
Une autre approche serait de créer images du patch 9 de votre image normale et de l’étendre à l’échelle que vous le souhaitez.
Vous pouvez le faire centrer le contenu en plaçant 9 points de raccordement dans les coins, ce qui préservera votre rapport de manière évidente (en supposant que le bord extérieur de votre image soit répétable/transparent).
J'espère que vous avez l'idée.
L'utilisation de la méthode décrite par a.ch a très bien fonctionné pour moi, sauf que j'ai utilisé ce type de balance qui fonctionnait beaucoup mieux pour ce dont j'avais besoin:
Android:scaleType="centerCrop"
Voici une liste complète des types de balance disponibles: http://developer.Android.com/reference/Android/widget/ImageView.ScaleType.html
Essayez d'utiliser InsetDrawable (a bien fonctionné pour moi).
Donnez simplement ceci à votre dessin et inserts (ou rembourrages) que vous voulez de l'un des quatre côtés.
InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom);
Il est spécifiquement utilisé pour la configuration d’arrière-plan dessinable, de taille inférieure ou égale à la vue.
Voir ici: https://developer.Android.com/reference/Android/graphics/drawable/InsetDrawable.html
Vieille question, mais aucune des autres réponses n'a fonctionné pour moi. Ce code xml a cependant:
<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 votre image bitmap est plus large que haute, utilisez Android:gravity="fill_vertical"
. Sinon, utilisez Android:gravity="fill_horizontal"
. Cela a un effet similaire à celui d'utiliser Android:scaleType="centerCrop"
Sur un ImageView
.
<bitmap xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:gravity="fill_vertical"
Android:src="@drawable/image" />
Si vous prenez en charge plusieurs orientations, vous pouvez créer un fichier XML bitmap dans le dossier drawable-port
Et l'autre dans le dossier drawable-land
.
Afin de fit l'image à l'espace disponible (ou si vous avez défini largeur et hauteur en dp), J'ai essayé l'approche suivante, même si l'image n'est pas trop large.
Ici, j'ai défini le même largeur et hauteur pour images carrées [ou vous pouvez wrap_content
à la fois].
<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>
adjust view bounds
et scale type center fit
fait le tour.