Comment faire en sorte qu'une image d'arrière-plan s'adapte à la vue tout en conservant son rapport hauteur/largeur lors de l'utilisation de <bitmap />
tant que XML pouvant être dessiné en arrière-plan ?
Aucune des <bitmap>
de android:gravity
ne donne l'effet souhaité.
Réponses
Trop de publicités?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 d'échelle dont vous avez besoin
Si votre bitmap est plus large que haut, utilisez android:gravity="fill_vertical"
. Sinon, utilisez android:gravity="fill_horizontal"
. Cela a un effet similaire à l'utilisation de 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
.
Une autre approche serait de créer des images patch 9 de votre image régulière et de l'étirer à l'échelle comme vous le souhaitez.
Vous pouvez le faire centrer le contenu en mettant 9 points de patch dans les coins qui préserveront évidemment votre rapport (en supposant que le bord le plus extérieur de votre image est répétable/transparent).
J'espère que vous avez l'idée.