Why is wrap_content bigger than real pixel size? - android

I am trying to understand something. A weird thing that I see is that when I put wrap_content in the width and hight, the image is bigger than the the real px (pixel) size of the image which is inserted. Why is that so?
My code with wrap_content:
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="false"
android:src="#drawable/header" />
and thats my code with exact pixel size of the image:
<ImageView
android:id="#+id/imageView1"
android:layout_width="378px"
android:layout_height="155px"
android:adjustViewBounds="false"
android:src="#drawable/header" />
As you can see, thats the exact pixel size:
Why is that? I thought that wrap_content should wrap the view to the content size so why is it bigger on screen?

If you really need to use the image's pixels as-is, and use the screen actual pixels do the following:
1) Create a res/drawable-nodpi and move your fixed-pixel non-scaling images in there.
2) You then can use wrap_content as layout_width and layout_height, and image pixels will match the device pixels with no upscaling because of dpi.
From http://developer.android.com/guide/practices/screens_support.html, the definition of nodpi :
Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.

A very nice explaintaion for supporting the multiple screens is given at
http://developer.android.com/guide/practices/screens_support.html.
you need to put images in respective folders after scaling.
e.g. if you want 100*100 image then place
75*75 in drawable-ldpi for Low density devices
100*100 in drawable-mdpi for Medium density devices
150*150 in drawable-hdpi for High density devices
200*200 in drawable-xhdpi for Extra High density devices

wrap_content means that you want the image as it as its original size is. i.e if the size of the image is 200*200 then it will show 200*200 and if the image size is 400*400 it will show of the size 400*400.
So the reason you are getting a larger image then what you actually get when you hard code it with real pixels is because of the LARGE SIZE of the image. i.e image is actually large.

From my experience I can say that wrap_content always utilize maximum available size possible. So sometimes it stretch the image & sometimes reduce the size of the image. To use exact image use android:scaleType="fitXY"
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="false"
android:scaleType="fitXY"
android:src="#drawable/header" />
Update after 1st 2 comments:
as per android docs :
You can specify width and height with exact measurements, though you probably won't want to do this often. More often, you will use one of these constants to set the width or height:
wrap_content tells your view to size itself to the dimensions required by its content
fill_parent (renamed match_parent in API Level 8) tells your view to become as big as its parent view group will allow.
In general, specifying a layout width and height using absolute units such as pixels is not recommended. Instead, using relative measurements such as density-independent pixel units (dp), wrap_content, or fill_parent, is a better approach, because it helps ensure that your application will display properly across a variety of device screen sizes. The accepted measurement types are defined in the Available Resources document.
I found the term size itself is important, it autometically resizes the images. thats why I told that from my experience I found sometimes it stretch the image & sometimes reduce the size of the image

You need to see where you put the image. If its in hdpi it will look bigger on screen then if its in hdpi when ising wrap_content. so, in order for it to be the exact size, put it in right library.

Related

Images appear to not scale up with the size of the screen

I have created a centered layout. But it does not scale images up to device's dpi. How to make them bigger as device screen? Also how to scale them even in editor? Cause I can't. They are always this size.
Here is an example of ImageButton code:
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/broadcasts"
android:background="?android:selectableItemBackground"
android:onClick="onWipButton_Click"
android:layout_marginRight="30dp"
android:layout_marginEnd="30dp"
android:id="#+id/imageButton2"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:scaleType="fitXY"
android:layout_above="#+id/textView5"
android:layout_toLeftOf="#+id/textView5"
android:layout_toStartOf="#+id/textView5" />
Folder structure with all dpi.
On device with high dpi.
Design mode in studio.
I'm assuming you have actually do have assets of different sizes in those resource folders at zoom levels of 1x, 1.5x, 2x, 3x, 4x for m, h, xh, xxh, xxxh.
Then understand that devices are not fixed width either physically or in terms of dps. So while it may be correctly picking the correct resource for the resolution of the screen, that does not mean it will take up the same % of available width on every device. It should just be roughly the same physical size if measure with a ruler (roughly the same mind you).
In the designer, pick a screen with the same width and DPI. You should see the issue at design time.
If you want larger images, providing larger assets would be the simplest solution, and won't make blurry scaled images.
Then if you want the larger images only for larger screens, you could provide the larger assets in a drawable folder for large screens:
res/drawable-mdpi/
res/drawable-sw600dp-mdpi/
res/drawable-hdpi/
res/drawable-sw600dp-hdpi/
etc.
sw600dp is a "smallest width" qualifier, meaning it applies when the device has at least 600dp width available to it. This is a commonly used number to distinguish devices, it's what used to be known as a large screen. If you want to support different assets for 10" tablets, you might also use sw720.
Please see here for more info on the screen size resource folder qualifiers: https://developer.android.com/guide/practices/screens_support.html#NewQualifiers

Wrap_contents or DP for ImageView

I see some people user the exact dp measurements for Imageview width and height in their layout while some others use wrap_contant.
Wrap_content would take the image size and display it accordingly. So if it is 60px by 60px then it will look smaller on high density screen and larger on low density screen.
While using the exact dp measurements lets say 60 dp, will make it look of the same size on all the screens.
As a result, shouldn't we be using the exact measurements all the time and not wrap_content? Am I missing something here
Thanks
I think if you use wrap_content, then the system will choose the resource from the appropriate resource folder depending on the screen density (mdpi, hdpi, xhdpi, etc) and will use the px dimension of that resource. Since the screen density resource folders (mdpi, hdpi, etc) can each apply to various screen densities (ie, mdpi is ~160dpi, but can be a bit less or a bit more before hitting the next density), this means that the image may change size slightly on different screens. If you specify the actual dp value for height and width, then you ensure the image will scale to maintain the same physical size on all devices.
Sometimes wrap_content is too small than what you want, or too big than what you want
so you can give exact measurements
If you want to make sure your exact measurements support multiple screen sizes, you can put them inside a dimens file which then loads according to the correct screen size
look into Support Multiple Screen Sizes
if for example you create a folder calld "values-sw600dp"
and put a dimen file in it, and have a property
<dimen name="imageSizeWidth">60dp</dimen>
And your image will be defined as follows
<ImageView
android:layout_width="#dimen/imageSizeWidth"
android:layout_height="#dimen/imageSizeWidth"
/>
Then it will be loaded, if the device matches the description "at least 600dp scree width"
this is providing there are other values folders in your resources.
If you don't have any other values folders, then this will be loaded by default

What is the scaleType I have to use here

I have an Image of resolution 1600 x 2400. I want it to be displayed in an ImageView as follow:
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside" />
I want the image to:
Take full width
Maintain Aspect ratio
Hence the imageview height must be as per the ratio
Eg: on a 320 x 600 screen, an image of size 1600 x 2400 must be shown as 320 x 480
What I currently get is an imageview with dimensions 320 x 2400 with image centered and space on top and bottom.
save the image in hdmi folder and use
android:src="#drawable/imagename"
or you can use
android:background="#drawable/imagename"
and you can set the heigth and width with
instead of fill parent or wrap or match use sizes in dp like 100dp or whatever you like.
android:layout_width="fill_parent"
android:layout_height="wrap_content"
example
android:layout_width="100dp"
1.Please go through the Developers guide first. Supporting Multiple Screens provides a pretty good overview of what you are trying to achieve. It's a challenging task being honest. Most of the iPhone devs enjoy the fixed screen size but we Android devs have to go through this problem. I can recomend few practices that I'm following
2.Try not to use Fixed height and weight as much as you can
Stick to Linear Layout if the layout is not complex. Go to relative layout only when its really mandatory.
Use Wrap and fill parent than giving fixed sizes..
These are the few I can think of.
3.Typically you just provide different layouts and resources for different screen densities and orientations as described in Android documentation
try using
android:scaleType="fitXY"
or
android:scaleType="fitCenter"
Assuming you have calculated how high your view should be: set it's layout parameters through code.
imageView.setLayoutParams(new LayoutParams(320, height));

Why my 720 px image got distortion in my 720 px galaxy S3

My question is just in the title.
I try to put an image to my layout, i tried this with a FrameLayout's background with wrap_content width and height and also tried with imageView with all of the possible fitScale properties.
I just cant see why my 720 px width image is HALF on the width of my phone's screen which is a samsung galaxy s3 with 720 px width....
My real question:
What is the best way to ensure that my pics in applicaion wont get any distortion?
First of all, you need to think in screen densities and dip values, not pixels. That means that you are dealing with a "virtual screen" where 1 dip (density independent pixel) represents a different amount of real screen pixels depending on the device.
For drawables you have the following categories for getting crisp results on any screen:
ldpi (Scale factor 0.75)
mdpi (Default / baseline: scale factor 1.0)
hdpi (1.5)
xhdpi (2.0)
Create different sized versions of your bitmaps based on these scale factors to get crisp results on any screen. You should start from xhdpi as highest resolution to avoid quality loss because of upscaling.
Put these different versions into their respective drawable folders (res/drawable-ldpi, res/drawable-mdpi...). These different versions of one and the same bitmap must bear the same file name of course, otherwise that won't work.
Second of all you shouldn't make strong assumptions about the device screen height and width. You need to layout your views and graphics so they dynamically make use of the whole screen not knowing the exact screen resolution. However, you can make weak assumptions about these screen resolutions based on the configuration qualifiers
small
normal
large
xlarge
Try to avoid fixed sizes for your views based on any assumptions. Always avoid "px" values in layout XML files. Use "dip" instead.
Read the documentation Supporting Multiple Screens for more information.
What you want to achieve sounds as if you want your image to take up the full width of the screen.
If you set the image as a background of any view (FrameLayout for example) then the displayed clip of the image depends on the size of that view.
If that view has layout_width / layout_height set to wrap_content then the size of it depends on the dimensions and arrangement of its child view(s).
In case of FrameLayout it depends on the size of that single child of FrameLayout.
If you're using ImageView the image will be scaled to fit into the size of the ImageView by default. The size of the ImageView depends on its layout_width / layout_height values. If you set these values to match_parent and if the ImageView has enough room "to grow" you should be able to see your image stretch all over the screen.
The "room to grow" depends on the ImageView's context in the layout. Does it have neighbors that take up room? Is the parent view too small (because of wrap_content for example)? Look for these possible problems.

Best fit the larger image into android device?

I have a larger image of 1024 x 768. When the image is displayed in the android device as the background image then it gets compressed. Is there any way that the image can be displayed properly in all screen resolution?
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:background = "#drawable/titlepage">
</RelativeLayout>
This is the code that I am using for setting the background image. But since the image is quite large it appears to be compressed when viewed on emulator or device.
Any help will be just great.
You are talking about multiple screen support. You need to make 3 types of images, HDPI, MDPI and LDPI. They have all different aspect ratios as well as different sizes.
Check out my tutorial on this subject, should explain everything.
http://wonton-games.blogspot.com/2010/07/tutorial-multiple-screen-support.html
or a simpler method if you just want to keep your aspect ratio is in your xml file using imageView do this
<ImageView
android:id="#+id/background"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#drawable/background"
android:adjustViewBounds="true">
</ImageView>
What this does is keep the aspect ratio of the image and fit it to the screen. You will get bars on either side if the aspect ratio doesn't match but this is just a quick shortcut way. You might have to play with layout_width/height to make it fit properly.
What you require is to maintain the resolution of the image, that would be the width:height ratio of the image. i am afraid for a 1024*768 the ratio is 1.33 , such image is meant for desktops. usually mobile devices have smaller ratio (w:h). eg: for Samsung galxy S , it would be 0.5, for Xperia X10, HTC Incredible, it would be 0.562. Android device screen sizes may vary. You need to have a suitable version of your image for each mdpi, ldpi and hdpi versions. Even then there is no guarantee that the image aspect ratio will be maintained. Better still have your image to be a 9 patch image, where you can define which part of the image should be stretched and which should be not, here you can preerve important part of the image.
Make an xml drawable file for the bitmap. You can change the gravity to "fill" You will still have issues with screens that are a different aspect ratio, but you can experiment with clamping, tiling, etc to get the look you want.
http://developer.android.com/guide/topics/resources/drawable-resource.html#bitmap-element

Categories

Resources