Skip to main content

Android: proportionally stretch an ImageView to fit the whole screen width while maintaining its aspect ratio

Proportional image resizing is a fairly common scenario while developing an Android app: there are a number of situations where you might want an image to stretch itself to horizontally fit the whole screen while keeping its original aspect ratio. You might think it should be easy: sadly, it’s not.

The problem

Achieving this result in HTML would be extremely easy: we just need to set our image width to 100% and avoid to set any height, letting the browser doing the whole proportional resize job. Unfortunately, Android wears a different pair of shoes: the ImageView element containing your drawable resource (or downloaded file) requires a width and an height: we can give a fixed number in px, dp or other supported units, use the parent width with the match_parent command or use the actual image width using the wrap_content command: as we can see, proportional resize is not an option. We can achieve some decent results by setting android:layout_widthandroid:layout_height and android:scaleType to make them adapt to the container layout in the following way:

These values could work in your specific scenario, but they tend to give inconsistant results among different devices and, most importantly, among different image sizes/ratios.

The solution

Why should we use a plain ImageView? We can start by taking a look to this interesting post on StackOverflow showing how to extend a View in order to achieve a very similar result: then we can use that knowledge to build our own ImageView extension class. Here’s an example of a ProportionalImageView which automatically scales its height according to its computed width keeping its original aspect ratio intact:

 

And this is how we can use it inside an XML layout:

Just remember to replace com.my.namespace with your app namespace and you should be fine.

Happy coding!

 

RELATED POSTS
 

Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies.

  • Pranjal

    Thank you boss.

     
  • Ali Aqdas Shah

    thnkx boss, it helped a lot

     
  • Nsamba Isaac

    Hello; Thanx for this. it was helpful
    but i have issue here, am having images in listview how can i reduce the size of the image(height) with out losing its ratio????

     
  • Alex

    Thank you very much sir. I’m facing issues related to stretch background every time I insert a drawable inside a Linear Layout. With this solution I found out ImageView can be used as a background and your code on onMeasure did the trick maintaining proportion.

     
    • You are very welcome!

       
  • DUNG

    Thank you BOSS, wonderful

     
  • Azri

    Hi, many thanks for the code. I have read thru also the stackoverflow thread. I have adjust the code so that the class know either to scale to height or width but it somehow get wierd result.

    the 0.752 is my imageview dimension ratio.

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Drawable d = getDrawable();
    if (d != null) {
    if (((float)(d.getIntrinsicWidth() / d.getIntrinsicHeight()))<0.752){
    int w = MeasureSpec.getSize(widthMeasureSpec);
    int h = w * d.getIntrinsicHeight() / d.getIntrinsicWidth();
    setMeasuredDimension(w, h);

    } else {
    int h = MeasureSpec.getSize(heightMeasureSpec);
    int w = h * d.getIntrinsicWidth() / d.getIntrinsicHeight();
    setMeasuredDimension(w, h);
    }
    }
    else super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

     
Read previous post:
#TwitterAcademy Feb-10 Italian Webinar: TwitterAnalytics, TwitterAds, QuickPromote and more

The first 2015 italian Twitter Webinar hosted by #TwitterAcademy ended a couple hours ago: it was mostly focused on an extensive...

Close