Fit Width of Background Image But Keep Aspect Ratio in Android
So you have an image that you want to use as a background on one of your activities.
You probably have something that looks like this.
But the desired effect is to scale the original image into the blue outline below.
The actual effect (depending on your current layout) is the graphic anchored to the top left (android:scaleType=”fitStart”) or center (android:scaleType=”fitCenter”) of the device’s screen with no scaling performed. Through all of your research on Google (directing you mostly to Stack Overflow threads) you’re stuck with a non-scaling graphic that’s positioned incorrectly on the screen. Or maybe you’ve got a distorted graphic that has stretched both in length and width and looks terrible. The short answer?
You can not scale the width of an ImageView to the screen’s resolution while maintaining aspect ratio in an Android layout using only XML.
That’s the information I got from one of the random Stack Overflows I found. And I ignored it for quite a while before giving in and trying to scale the image manually through code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/iv_background" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitCenter" android:src="@drawable/the_background" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/b_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:text="@string/login_button" /> </LinearLayout> </RelativeLayout> |
And the necessary code placed at the bottom of the activity’s onCreate method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int height = metrics.heightPixels; int width = metrics.widthPixels; BitmapDrawable bmap = (BitmapDrawable) this.getResources().getDrawable(R.drawable.the_background); float bmapWidth = bmap.getBitmap().getWidth(); float bmapHeight = bmap.getBitmap().getHeight(); float wRatio = width / bmapWidth; float hRatio = height / bmapHeight; float ratioMultiplier = wRatio; // Untested conditional though I expect this might work for landscape mode if (hRatio < wRatio) { ratioMultiplier = hRatio; } int newBmapWidth = (int) (bmapWidth*ratioMultiplier); int newBmapHeight = (int) (bmapHeight*ratioMultiplier); ImageView iView = (ImageView) findViewById(R.id.iv_background); iView.setLayoutParams(new LinearLayout.LayoutParams(newBmapWidth, newBmapHeight)); |
This results in an ImageView that’s stretched to fit the width of the screen while maintaining the aspect ratio of the image.