69 votes

Mettre l'image à l'échelle en gardant son rapport hauteur/largeur en arrière-plan dessinable

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é.

5voto

Kamen Dobrev Points 741

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

3voto

Jason Robinson Points 10878

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 .

3voto

xbakesx Points 3419

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X