Here is my problem:
I put a image with resolution 200x200 in a imageview with height and width both be 200dip, but the image shown seemed larger than 200x200, here is how I found the problem.
I use below code to get the width and height of my screen. And found out my screen is 540x800, but the image width is larger than half of my screen.
WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
width = wm.getDefaultDisplay().getWidth();
height = wm.getDefaultDisplay().getHeight();
Is there anyone who can tell me why. Below is the xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation = "vertical"
android:background = "#drawable/mainbg2"
>
<LinearLayout
android:orientation="horizontal"
android:id="#+id/layout_menu_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ImageView
android:id="#+id/img_menu_normal"
android:layout_width="200dip"
android:layout_height="200dip"
android:src="#drawable/menu_normal"/>
</LinearLayout>
</RelativeLayout>
Check this documentation.
Density-independent pixel (dp)
A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the
system for a "medium" density screen. At runtime, the system
transparently handles any scaling of the dp units, as necessary, based
on the actual density of the screen in use. The conversion of dp units
to screen pixels is simple: px = dp * (dpi / 160). For example, on a
240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use
dp units when defining your application's UI, to ensure proper display
of your UI on screens with different densities.
So I assume that your device is not mdpi which use bigger scale ratio. If you want to make exact pixel size on you device you can use 200px. But first check the documentations link above.
it's display 200X200 dp size image in view you can check using this xmp change in you file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/layout_menu_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal" >
<ImageView
android:id="#+id/img_menu_normal"
android:layout_width="200dip"
android:layout_height="200dip"
android:background="#android:color/black"
android:src="#drawable/ic_launcher" />
</LinearLayout>
i hope you can understant what happen there. i am set image in centre of relative view and change background color of imageview to black and main view bg color to white.it's working code.
Related
I use a imageView to show an image on activity . This image size shouldn't change according to the device screen . But This is not working . I want use the actual size of the image for every device. Below is what I have tried .
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/circle"
android:id="#+id/imageView"
android:scaleType="center"/>
</RelativeLayout>
How could I use same image size without scaling on each device screen ?
Have any ideas.
Thank you.
Use inches instead of pixels size
for example, android:layout_width=".5in"
<ImageView
android:layout_width="1in"
android:layout_height="1in"
android:src="#drawable/circle"
android:id="#+id/imageView"
android:scaleType="center"/>
https://developer.android.com/guide/practices/screens_support.html
You have to design layouts for every screen size or you should declare your dimens in different dimes folders instead of wrap_content because it will scale your image according to screen density,
values folders which you have to create with dimens are:
values-hdpi/dimens.xml------for hd handsets
values-xhdpi/dimens.xml-----for 5" screens xHD
values-xxhdpi/dimens.xml----for nexus 5X
values-xxxhdpi/dimens.xml----for nexus 6 and 6P devices
values-sw720dp/dimens.xml-----for 9" tablets
values-sw800dp-hdpi/dimens.xml--------for 10" tablets
values-sw600dp/dimens.xml------for 7" tablets
For this purpose, you have to define the static fixed height and width to your ImageView and then use the following attribute:-
imgview.setScaleType(ScaleType.FIT_XY);
Just inspect the actual size of jour image using a software like photoshop or gimp, then set the real width and height (e.g.: 50px x 40px)in your imageview in this way:
<ImageView
android:layout_width="50px"
android:layout_height="40px"
android:src="#drawable/circle"
android:id="#+id/imageView"
android:scaleType="center"/>
Just Do it in this way!! The height is fixed so you need to provide a value for height and the width must be match_parent.Its working perfectly fine for me.
<ImageView
android:id="#+id/img_saving_image"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_centerHorizontal="true"
android:src="#drawable/ic_cross"
android:scaleType="fitCenter"
or
android:scaleType="fitXY"
/>
Put your image in drawable or drawable-nodpi.
Android will not scale your image size.you code do not need to change.
Use fixed width and height in dp.
The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.
Source
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/circle"
android:id="#+id/imageView"
android:scaleType="center"/>
For more information about DP, SP, px. Please see What is the difference between px, dip, dp, and sp?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/gray"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/darkgray"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/attenders"
android:layout_width="110dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="#color/gray"
android:layout_marginRight="8dp"
android:text="Attenders" />
<Button
android:id="#+id/send"
android:layout_width="110dp"
android:layout_height="40dp"
android:layout_marginLeft="8dp"
android:layout_gravity="center"
android:background="#color/gray"
android:text="Send IM" />
</LinearLayout>
</LinearLayout>
this is my code but the dp is not working fine for all screen resolutions.
suggestions plz, plz tell me if i am doing anything wrong
problem is that when i use dp for setting height or width of a button
it does not gets fits to all resolutions i-e on small screens it looks
big and on big screens it looks small, whereas i know that when we use
dp for setting height and width of any component it automatically
converts/adjusts according to screen resolution
What I understand from this is that you thought using dp instead of px (or in, or cm) will magically work such that they will all have the same physical size on all devices, regardless of that device's density (ppi).
That's not the case.
dp, or dip, as explained here, is
An abstract unit that is based on the physical density of the screen.
These units are relative to a 160 dpi (dots per inch) screen, on which
1dp is roughly equal to 1px.
A screen with more dpi (denser, meaning more pixels are packed into a square area of the screen), will essentially draw a physically smaller image compared to a screen that has 160dpi when tasked to draw the same, say, 100x100 dp image.
When running on a higher density screen, the number of pixels used to
draw 1dp is scaled up by a factor appropriate for the screen's dpi.
Solution
There are two easy ways to have your app look proportionally the same on different screen sizes.
The first is to use different layout folders (layout-ldpi, layout-mdpi, etc.). This technique is well-explained here. A much more recommended way would be to use different style values for each density, so you can still maintain one layout folder and refer to the styles instead for measurement. This can be done using the same technique, but instead you will have values-ldpi, values-mdpi, etc. This is useful for having standard sized UI elements across screen sizes.
The other way is to use weights all over your layout. Weights adjust automatically regardless of screen size of density. This will help a lot if you want, say, three columns that have varying width -- you can easily use weights to tell the layout that column A needs to occupy 40% of the available width of the screen, and B and C will have 30% each. This is useful for having a standard layout across screen sizes.
A clean-looking, nicely coded app will implement both.
It is beacause you are giving fixed dimensions which can only be fit for a particular screen size which you are using. So try avoiding static dimensions and make use of match_parent,wrap_content and fill_parent so that you can get your layout fit for every screen size.
I have ready many, many tutorials, I have read http://developer.android.com/guide/practices/screens_support.html for the 3rd time, but I still don't know how to set layouts to be compatible for multiple screens.
On android docs I found this:
For instance, a view with a layout_width="100dp" measures 100 pixels
wide on medium-density screen and the system scales it up to 150
pixels wide on high-density screen, so that the view occupies
approximately the same physical space on the screen.
Ok, let's see an example:
As you can see, the resolution is the same (480x800), however the view does not fill till end. I know I should use fill_parent, or match_parent, but this is for test purpose only.
XML Layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:weightSum="100"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="320dp"
android:layout_height="0dp"
android:layout_weight="45"
android:background="#drawable/bg_red" >
</RelativeLayout>
<RelativeLayout
android:layout_weight="10"
android:layout_width="fill_parent"
android:layout_height="0dp" >
</RelativeLayout>
<RelativeLayout
android:layout_width="320dp"
android:layout_height="0dp"
android:layout_weight="45"
android:background="#drawable/bg_blue" >
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
Dp or dip (density-independent pixels) takes the device's density into account. The purpose of density-independent pixels is to display a view in the same physical dimensions on screens of any density.
How many actual pixels a dip equals depends on your device's density:
If you have an mdpi device, one dpi equals one pixel (factor = 1)
On a hdpi device, one dpi is two pixels, which should be
approximately as big in physical size as the one pixel on mdpi. (factor = 2)
It all gets a bit clearer on an actual device:
Your 480*800 hdpi device would be smaller in physical size than the 480*800 mdpi device. Thus, when a view fills the hdpi device's screen, a view with the same physical size (dp) won't fill the screen on your mdpi device.
I have a banner which is 320dp wide but it is filling the entire width of a 480x800 android emulator.
Here is the XML for the banner:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/add_banner"
android:layout_width="320dip"
android:layout_height="50dip"
>
<ImageView android:id="#+id/add_image"
android:layout_width="320dip"
android:layout_height="50dip"
android:src="#drawable/your_ad_here"
/>
<Button android:id="#+id/btn_addclose"
android:layout_width="25dip"
android:layout_height="25dip"
android:gravity="center"
android:layout_alignTop="#id/add_image"
android:layout_alignRight="#id/add_image"
android:text="x"
/>
</RelativeLayout>
I have included it in my main.xml file as :
<include android:id="#+id/add_banner"
layout="#layout/tlp_add_banner"
android:layout_width="320dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
To make sure that my emulator is 480x800, I even logged the metrics on runtime. It is 480x800. Then why is the banner taking up the entire width?
dip means density-independent pixels. Your 480x800 emulator is most probably HDPI (high density, or high dots per inch), which means that 320dp will translate to 320*1.5 actual pixels (which is 480). Only on an MDPI (medium density) screen, where the scale factor is 1 will you actually get 320 pixels.
You can get the scale factor for the current screen like this:
float scale = getResuorces().getDisplayMetrics().density;
If you really want it to be 320 pixels wide, regardless of the screen density (this is not recommended at all), you can just specify:
android:layout_width="320px"
dip aren't physical pixels but a made up number that depends on the display density. More info here:
http://developer.android.com/guide/practices/screens_support.html
I am using WVGA800 skin in Android emulator, so the density (hw.lcd.density) is 240. I have to put 4 image buttons (72 pixels per inch) at the bottom of activities view. As the resolution is 480X800, I asummed that the width of image must be 120 pixels. The problem is when application is launched, the 3 buttons take all width and there is no place for 4th button... Then I created button image in Fireworks with resolution 240 pixels per inch and in 120px width, but problem remains. Could somebody explain how to make correct drawables (sizes and dpi) so that they can be displayed pixel in pixel on Android?
If you put your images in res/drawable, Android assumes they're for 160dpi and scales them accordingly for different resolutions.
Your options are either to put the button images into res/drawable-hdpi signaling that they're intended for densities around 240dpi, or into res/drawable-nodpi to make them never scale regardless of the current screen density.
You still reference them as #drawable/whatever in layouts, the engine picks the best match automatically.
Disregard the image DPI entirely. It's irrelevant, all you need to know is the pixel size. What I would actually suggest is to create a NinePatch image to use as your button background. You'll actually need a few to put into a StateListDrawable, as this is how the different focus states are defined (e.g. Pressed, Focused). Once you have your NinePatch, just create a LinearLayout like so:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/my_nine_patch"
android:text="button 1"
android:layout_weight="1"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/my_nine_patch"
android:text="button 2"
android:layout_weight="1"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/my_nine_patch"
android:text="button 3"
android:layout_weight="1"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/my_nine_patch"
android:text="button 4"
android:layout_weight="1"
/>
</LinearLayout>
Set all the buttons to fill_parent and give them all an equal weight. They'll stretch to fit evenly to the parent, and you don't have to worry at all about specifying a constant pixel or dip size. Also, it'll evenly split onto any Android device, no matter the resolution.
The width is actually 320 pixels, so for 4 buttons across the entire screen set each to 80dip. Android will then adjust your density independent pixels to the proper screen size of 480 pixels.