title: How to have a Fullscreen Background Image (with center-crop) that doesn't Resize
body: <p>I'm trying to set a photo as the background of an <code>Activity</code>. I want the background to be <a href="https://stackoverflow.com/questions/16135984/full-screen-background-image-in-an-activity">a full screen image (no borders)</a>.</p>
  
  <p>As I want the image to fill the entire activity's background without stretching/squeezing (i.e. unproportional scalings for X and Y) and I don't mind if the photo has to be cropped, I'm using a <code>RelativeLayout</code> with an <code>ImageView</code> (with <code>android:scaleType="centerCrop"</code>) and the rest of my layout consisting of a <code>ScrollView</code> and its children.</p>
  
  <pre><code>&lt;!-- Tried this with a FrameLayout as well... --&gt;
  &lt;RelativeLayout&gt; 
     &lt;!-- Background --&gt;
     &lt;ImageView  
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/&gt;
     &lt;!-- Form --&gt;
     &lt;LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"&gt;
        &lt;ScrollView&gt;
          &lt;LinearLayout&gt;
            ...
            &lt;EditText/&gt;
          &lt;/LinearLayout&gt;
        &lt;/ScrollView&gt;
     &lt;/LinearLayout&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>The problem is that the rest of the layout has some <code>EditText</code> views and when the softkeyboard shows up, the ImageView gets re-sized. I would like the background to remain the same, irregardless of whether the softkeyboard is visible or not.</p>
  
  <p>I have seen <a href="https://stackoverflow.com/questions/4287473/android-soft-keyboard-resizes-background-image">plenty of questions</a> on SO about ImageViews being re-sized but (imo) no satisfactory answers. Most of them just consist of setting the <code>android:windowSoftInputMode="adjustPan"</code> - which is not always practical, especially if you want the user to be able to scroll in the activity - or using <code>getWindow().setBackgroundDrawable()</code> which doesn't crop the image.</p>
  
  <p>I've managed to sub-class ImageView and override its <code>onMeasure()</code> (see my answer here: <a href="https://stackoverflow.com/questions/15136193/imageview-resizes-when-keyboard-open/21758219#21758219">ImageView resizes when keyboard open</a>) so that it can force a fixed height &amp; width - equal to the device's screen dimensions - according to a flag but I'm wondering if there's a better way of achieving the result I want.</p>
  
  <p>So, to sum up, my question is: <strong>How can I set an Activity's background to be a full-screen photo</strong> </p>
  
  <ul>
  <li><p><strong>with scale type = "centerCrop", so that the photo is scaled uniformly (maintaining its aspect ratio) and therefore both dimensions (width and height) of will be equal to or larger than the corresponding dimension of the view;</strong></p></li>
  <li><p><strong>that doesn't get resized when a softkeyboard pops up;</strong></p></li>
  </ul>
  
  <hr>
  
  <p><strong>ANSWER:</strong></p>
  
  <p>I ended up following <a href="https://stackoverflow.com/users/2252830/pskink">@pskink</a>'s advice and subclassed <code>BitmapDrawable</code> (see his answer bellow). I had to do some adjustments to make sure that the <code>BackgroundBitmapDrawable</code> is always scaled and cropped in a way that fills the screen.</p>
  
  <p>Here's my final class, adapted from his answer:</p>
  
  <pre><code>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() &gt; 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 -&gt; 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 &gt; 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);
      }
  }
  </code></pre>
  
  <p>Then its just a matter of creating a <code>BackgroundBitmapDrawable</code> and setting it as the root View's background.</p>