Comment avoir une image d'arrière-plan en plein écran (avec recadrage au centre) qui ne soit pas redimensionnée

Je suis en train de définir une photo comme arrière-plan d'une Activity. Je veux que le fond une image en plein écran (sans frontières).

Que je veux l'image pour remplir l'ensemble de l'activité de l'arrière-plan, sans étirement/presser (c'est à dire disproportionnées la mise à l'échelle pour X et Y) et je n'ai pas l'esprit si la photo doit être recadrée, je suis en utilisant un RelativeLayout avec un ImageView (avec android:scaleType="centerCrop") et le reste de mon réseau constitué d'un ScrollView et de ses enfants.

<!-- Tried this with a FrameLayout as well... -->
<RelativeLayout> 
   <!-- Background -->
   <ImageView  
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:scaleType="centerCrop"/>
   <!-- Form -->
   <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent">
      <ScrollView>
        <LinearLayout>
          ...
          <EditText/>
        </LinearLayout>
      </ScrollView>
   </LinearLayout>
</RelativeLayout>

Le problème est que le reste de la mise en page a certains EditText points de vue et lors de la softkeyboard montre, l'ImageView obtient re-dimensionnées. Je voudrais que le fond reste le même, indépendamment de savoir si le softkeyboard est visible ou non.

J'ai vu beaucoup de questions sur DONC environ ImageViews être redimensionnées mais (omi) pas de réponses satisfaisantes. La plupart d'entre eux seulement se composent de définition de la android:windowSoftInputMode="adjustPan" - qui n'est pas toujours pratique, surtout si vous voulez que l'utilisateur soit capable de faire défiler à l'activité ou à l'aide de getWindow().setBackgroundDrawable() qui n'a pas de recadrer l'image.

J'ai réussi à la sous-classe ImageView et de remplacer son onMeasure() (voir ma réponse ici: ImageView est redimensionnée lorsque le clavier ouvert), de sorte qu'il peut forcer une hauteur fixe & largeur égale à l'écran de l'appareil dimensions - selon un drapeau mais je me demandais si il ya une meilleure façon d'atteindre le résultat que je souhaite.

Donc, pour résumer, ma question est: Comment puis-je définir une Activité d'arrière-plan plein écran photo

  • avec le type d'échelle = "centerCrop", de sorte que la photo est mise à l'échelle uniforme (en maintenant son ratio d'aspect) et donc à la fois les dimensions (largeur et hauteur), sera égal ou plus grand que la dimension correspondante de la vue;
  • qui n'est pas redimensionnée avec un softkeyboard pop-up;

RÉPONSE:

J'ai fini par suite de @pskink's des conseils et des sous-classé BitmapDrawable (voir sa réponse ci-dessous). J'ai dû faire quelques ajustements pour s'assurer que le BackgroundBitmapDrawable est toujours mise à l'échelle et recadrée de façon à remplir l'écran.

Voici ma dernière classe, adapté de sa réponse:

public class BackgroundBitmapDrawable extends BitmapDrawable {
private Matrix mMatrix = new Matrix();
private int moldHeight;
boolean simpleMapping = false;
public BackgroundBitmapDrawable(Resources res, Bitmap bitmap) {
super(res, bitmap);
}
@Override
protected void onBoundsChange(Rect bounds) {
if (bounds.height() > moldHeight) {
moldHeight = bounds.height();
Bitmap b = getBitmap();
RectF src = new RectF(0, 0, b.getWidth(), b.getHeight());
RectF dst;
if (simpleMapping) {
dst = new RectF(bounds);
mMatrix.setRectToRect(src, dst, ScaleToFit.CENTER);
} else {
//Full Screen Image -> Always scale and center-crop in order to fill the screen
float dwidth = src.width();
float dheight = src.height();
float vwidth = bounds.width(); 
float vheight = bounds.height();
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight; 
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
mMatrix.setScale(scale, scale);
mMatrix.postTranslate(dx, dy);
}
}
}
@Override
public void draw(Canvas canvas) {
canvas.drawColor(0xaa00ff00);
canvas.drawBitmap(getBitmap(), mMatrix, null);
}
}

Alors c'est juste une question de la création d'un BackgroundBitmapDrawable et de la définir comme la racine de la Vue d'arrière-plan.

source d'informationauteur user1987392