Setting ImageView ScaleType to "center" does not work as I expect

I have the following layout for my ImageView :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:descendantFocusability="blocksDescendants"> <ImageView android:id="@+id/imageview_icon" android:layout_width="48dp" android:layout_height="48dp" android:scaleType="fitCenter" /> (...) </LinearLayout> 

Those 48dp are 36px, 48px and 72px in ldpi , mdpi and hdpi respectively. All the images that will be used in this ImageView are basically icons, and I found on the Internet what I want for my application (free license). But, unfortunately, it does not come with images larger than 48 pixels, and the use of different images is out of the question. So I need a new solution ...

Now I have 36px and 48px images in the ldpi and mdpi , respectively. But I have problems with hdpi . For devices running on hdpi , I want to use the mdpi image (larger) and use it as is, without scaling. Basically, the ImageView for hdpi is 72px, so I want the 48px image to be inside 72px, in the center, without scaling. To do this, I just tried changing the scaleType in the ImageView above to just center , but the image still scales.

My final question here is, what is the correct way to fix the problem described above? How can I use ldpi and mdpi images at their respective densities, but devices running under hdpi have the largest available image (these are mdpi tags) and prevent any scaling by simply fitting the image in the center of the ImageView ?

EDIT:
I myself answered this question, but it may be the answer that others who come here are looking for. But I give some idea of ​​what is actually happening, and of the underlying problem. Please take a look and provide a workaround / fix if you can. I dare you :)

+4
source share
7 answers

This question is without question, and I apologize to everyone who found it, hoping that the accepted answer will be what they are looking for when it does not.

To make it clear, scaleType=centerInside works as expected. That is, if you have an image smaller than the ImageView itself than this image will not scale to the borders of the ImageView , it will remain in the center and unscaled.

But in order for the above to work as expected, the nodpi must be placed in the nodpi folder. I understand that this is not always acceptable. Therefore, when this drawable should be placed in one of the density folders instead of the nodpi folder, the scaleType attribute will only work in certain situations.

When it will work:

  • You use the application on a device / emulator with an Xdpi density and in the Xdpi density Xdpi there is the possibility of drawing (here X means l , m , h or even xh ).
  • You have launched an application / application emulator, for example, with hdpi density, but in hdpi , and the system selects an alternative that can be extracted from nodpi (it is not always known which folder it will choose from).

When this does not work:

  • You have launched the application / application emulator, for example, using hdpi density, but there is no picture in the hdpi folder, and the system selects an alternative to be extracted from any other folder density (not the nodpi folder), then the nodpi one will be scaled to ImageView , and the scaleType attribute scaleType not there will be something.

In conclusion, there is no “right” answer to my question, it really depends on what you are trying to achieve. The answer to my question, though, I just need to do 2 things: a) Set ImageView scaleType to centerInside and b) Duplicate all the drawings from the mdpi folder to the hdpi folder (as described above, scaleType=centerInside will make it work).

Of course, duplicating the drawings is not optimal, but I can’t find another solution, and so far no one else could ... So, at present I will mark this as accepted.

What would be the best answer / solution?
In my opinion, if the device / emulator works in hdpi , and there is no suitable picture in the hdpi folder, it should choose to extract from the mdpi folder without scaling, which allows the scaleType attribute to do this. Or, perhaps, make the system go to the nodpi folder if it does not find a suitable upload in the corresponding density folder, which can also help.

So, if anyone can ever provide a workaround / fix for this problem, this will be the correct correct answer. If it ever comes to this, I will change the accepted status.

+13
source

I solved it as follows:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <!-- Here is where the money is --> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_horizontal|center_vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> ... </LinearLayout> </LinearLayout> 
+1
source

In my case, I set the image as android:background . when i installed it as android:src , it will work!

+1
source

Try to leave it in the hdpi folder and put it in the drawable-nodpi folder. I'm not sure what a hierarchy is (can nodpi override the ldpi and mdpi folders), but that would be my first attempt.

0
source

Try the following:

 <FrameLayout android:layout_width="48dp" android:layout_height="48dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:maxWidth="48px" android:maxHeight="48px" android:adjustViewBounds="true" android:src="..." /> </FrameLayout> 

And put the images usually in the ldpi / mdpi folders.

Although I do not recommend using pixel values.

0
source

Try

 imageview.setAdjustViewBounds(false); 
0
source

Create your own ImageView:

 package x; public class MaxMDPIImageView extends ImageView { public MaxMDPIImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { float density = getResources().getDisplayMetrics().density; if (density>1) { canvas.translate(getWidth()/2-getWidth()/density/2, getHeight()/2-getHeight()/density/2); canvas.scale(1/density, 1/density); } super.onDraw(canvas); } } 

Use it just like:

 <x.MaxMDPIImageView android:src="@drawable/icon" android:layout_width="wrap_content" android:layout_height="wrap_content"/> /> 
-1
source

All Articles