35

A guide for Android ImageView ScaleType and adjustViewBounds

 5 years ago
source link: https://www.tuicool.com/articles/hit/YzUnUbM
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

For a long time we’ve had this bug in our Live TV section where some of the channel logos were squashed. I finally decided that it was time to fix it.

BZV7va2.png!web
SkySports main event and SkySports football logos are squashed

The bug

In the image above you can clearly see the SkySports main event logo is squashed, the same happens with SkySports football although is less noticeable and finally SkySports Premier League is showing just fine. The question is why?

Below is part of the code from our ImageView. We are trying to say that we want to resize our logos to always have an 18dp height and then use whatever width they need. We also had set scaleType to fitXY .

android:layout_width="wrap_content"
android:layout_height="18dp"
android:scaleType="fitXY"

Let’s have a look at what fitXY does.

BV7NRjm.png!web

In theory this doesn’t look really bad, we are going to have our fixed height and then it’s going to scale our image filling the width. But we know this doesn’t really work so let’s dig in a little bit more and see what Matrix.ScaleToFit.FILL does.

bmayauE.png!web

The image is going to scale X and Y independently which may change the aspect ratio of it. That is exactly what’s happening, the aspect ratio of the image is changing and stretching it.

adjustViewBounds to the rescue

Fortunately there is a really simple way to preserve the aspect ratio of the image while keeping control of one dimension (in our case the height). When we set adjustViewBounds to true we are telling the ImageView (not the drawable) to adjust its bounds to preserve the aspect ratio of its drawable.

android:layout_width="wrap_content"
android:layout_height="18dp"
android:scaleType="fitXY"
android:adjustViewBounds="true"

By adding adjustViewBounds and leaving the layout_with as wrap_content we are keeping the aspect ratio of the image while keeping the height to 18dp but letting the width change accordingly, so we are still able to control the size of the image (kind of) and maintaining the aspect ratio at the same time.

RZVja2M.png!web
All the logos are scaled and keep the aspect ratio

This was a really simple fix and actually we just had to do it in our tablet layouts because our phone layout already had adjustViewBounds set to true.

I could have left it like this and move on but I thought that it would be interesting to check what would happen if I were to use all the different types of scaling that we have available. So here are the results.

Experimenting with scaleType

We already know what happens when we use fitXY so let’s have a look at the other types that we can use. For the following experiments I will be using adjustViewBounds first and then disabling it to see how it affects the rendering of the images.

beARjmJ.png!web

adjustViewBounds=true

B3EJRrV.png!web
Using adjustViewBounds

Here we are centering the image without any scaling and because we are keeping the aspect ratio of the ImageView with adjustViewBounds the size of the ImageView (not the image) keeps the aspect ratio of the image.

adjustViewBounds=false

fEBjYzQ.png!web
Without adjustViewBounds

In this case we are not using adjustViewBounds so the ImageView is not keeping the aspect ratio and that’s why the width has massively increased. The image is still centered.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK