I did my analysis and found that most of the users of my application will be of samsung galaxy S2, and samsung galaxy note . Doing research on their technical spec, I found:
Galaxy S2:
480 x 800 pixels, 4.3' display
Galaxy Note:
1280 x 800, 5.3ā€¯screen
How can I categorize these into Layout size and desnity level? I think I can figure out the layout size as mentioned in the android development page
However I am unable to know the density level (low, medium high xhigh). They say that I need the dpi but in functional spec, I rarely see the dpi, I just see the above resolution
Thank you
Calculate the density first Density=Square root((wp*wp)+(hp*hp))/di
where wp is width resolution in pixels, hp is height resolution in pixels and di is diagonal size in inches. It would come ~208 for S2.
ldpi ~120dpi,mdpi ~160dpi, hdpi~240dpi, xhdpi ~320dpi. Compare from these values of dpi
Not sure if I understand you correctly but you can request the density level and the dpi from the DisplayMetrics class. Using resolution and density you can approximate the display's size.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Related
I'm struggling with a pretty trivial task in the Android "multiple-screen sizes" domain.
What I'm trying to achieve
A layout matching the screen width, with a nine-patch background which resizes (only horizontally, since there is always enough vertical space). Here is a dummy image:
My goal is, depending on the screen resolution, to display the image at the highest resolution possible, by using a set of different sizes, eg. 320x45, 480x67, 600x87, 720x101, without any down-scaling. I'm hoping for a non-programmatic solution.
An example with the above mentioned image sizes would be:
3.7" Nexus One (480 x 800) - the 480x67 image would look best.
4.7" Galaxy Nexus (720 x 1280) - the 720x101 image.
4.7" Nexus 4 (768 x 1280) - again the 720x101 image, stretching to the full 768 px width and becoming 768x101.
Issue
The whole Android resource allocation revolves around dps (density-independent pixels), when in fact I want to display an image based on the actual available pixels.
If I allocate the 480x67 image to res/drawable-mdpi and a 600x87 to res/drawable-hdpi, then image would display correctly on a 5.4" display of 480x800, i.e. mdpi display. However, a 4" 480x800 displays qualifies as hdpi and the system would appoint the 600x87 image, which won't fit the screen.
I tried the smallestWidth parameter as described in the online guide, but that yields strange results. For instance, a 3.7" 480 x 800 display (hdpi) uses my drawable-sw320dp image, although there is a drawable-sw480dp resource available too.
What is the best way to assign a stretchable, width-matching image with the best possible quality? Isn't there any non-programmatic solution?
Thanks in advance!
I believe that by combining density and screen size resource qualifiers you can achieve a close to optimal behavior.
Lets assume this kind of resource folders structure:
drawable-normal-hdpi - A normal size dictates minimum width of
320dp. hdpi dictates 1.5X dp to pixel multiplier. So the minimum px
width of the normal hdpi bucket is 480px. We put here a 480px wide
image.
drawable-normal-xhdpi - Again size dictates 320dp but this time
with 2X multiplier. So we use a 640px wide image.
drawable-xlarge-mdpi - Size means at least 720dp. mdpi multiplier
is 1X, so we use a 720px wide image.
Now lets look at some devices to see how they fall in with those buckets:
Nexus one - normal hdpi. Actual px width: 480px. The image fits
perfectly.
Galaxy nexus - normal xhdpi. We could fit a 720px image, so the
640px image we use isn't optimal - but it's very close.
Nexus 4 is just like the Gnex.
Nexus 10.1 (1280X800) - xlarge mdpi. We could fit 800px, our image
is 720px. Again not ideal but close enough.
Worst case scenario: image used could have 5-10% better quality.
Best case: perfect fit.
The main down side of this method is that you need to provide a lot of resources and folders to account for all the permutations of sizes and densities (even worse if you need to combine that with more qualifiers for locale, orientation and so on). However, as far as my Android understanding goes I don't think you can achieve something better than this without coding.
A remark regarding smallestWidth: Your example for the weird behavior is actually the expected behavior.
hdpi multiplier is 1.5 - So a 480px wide hdpi display is exactly 320dp wide. This makes the drawable-sw320dp the right choice, as documented. I'm not sure if you can combine the smallestWidth qualifier with the dpi qualifier. If it's possible you might get more accurate results than just size modifiers. But this would mean a lot more permutations for a 5% increase in image quality. Probably not worth it.
Actually, your method is not how it is supposed to be. I will suggest 2 ways for you, one is easy but doing programmatically, other one is using a custom view.
Method 1 - Programmatically
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
// this will determine "scale ratio" so using which image height and width won't matter
int imageOriginalHeight = 101; // your original image height
int imageOriginalWidth = 720; // your original image width
int imageScaleHeight = (screenWidth*imageOriginalHeight) / imageOriginalWidth;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, imageScaleHeight);
imageView.setLayoutParams(params);
imageView.setImageResource(R.drawable.file);
Method 2 - Custom View
You can use a custom view called ScaleImageView which is written by Maurycy Wojtowicz.
Class is defined like below:
This view will auto determine the width or height by determining if
the height or width is set(exact size or match_parent) and scale the
other dimension depending on the images dimension This view also
contains an ImageChangeListener which calls changed(boolean isEmpty)
once a change has been made to the ImageView
Here is how you are going to implement it.
Create a class named ScaleImageView.java and copy contents of the link above.
In your xml file, create a ScaleImageView, just same like ImageView (the example I am writing below is for filling screenwidth, and scaling height according to that so there will be no empty spaces on right/left)
<com.project.customview.ScaleImageView
android:id="#+id/scaleImageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/file" />
If you need to declare and set programmatically in your Activity, it is also the same as using ImageView:
imageView = (ScaleImageView)findViewById(R.id.scaleImageView);
imageView.setImageResource(R.drawable.file);
In android you have the option hdpi, mdpi, xdpi,etc..
folders for that , you have to create different images according your device resolution and put your images at there after confirming your device resolution and density category.
for the more reference why it'll happen you can see here
here i explain some chart may be helpful to you.
Low density Small screens QVGA 240x320 (120dpi):
drawable-small-ldpi (240x320)
drawable-small-land-ldpi (320x240)
Low density Normal screens WVGA400 240x400 (x432) (120dpi):
drawable-ldpi (240 x 400 )
drawable-land-ldpi (400 x 240 )
Medium density Normal screens HVGA 320x480 (160dpi):
drawable-mdpi (320 x 480 )
drawable-land-mdpi (480 x 320 )
Medium density Large screens HVGA 320x480 (160dpi):
drawable-large-mdpi (320 x 480 )
drawable-large-land-mdpi (480 x 320)
Galaxy Tab ( 240 dpi ):
drawable-large (600 x 1024)
drawable-large-land (1024 x 600)
High density Normal screens WVGA800 480x800 (x854) (240 dpi):
drawable-hdpi (480 x 800)
drawable-land-hdpi (800 x 480)
Xoom (medium density large but 1280x800 res) (160 dpi):
drawable-xlarge (800 x 1280)
drawable-xlarge-land (1280 x 800)
I am new to tablet application development. I am having Google Nexus7 with screen resolution (600 * 960 dip) So I want to know is it fall in to mdip category?
According to that 1px = 1dp (baseline). But If I follow this its not looks good on tablet. I am creating separate layout folder for nexus7 -sw600dp and mention sizes according to mdip but it not working. My images also not looking good. What I want to know what is actual conversion rate for google nexus 7. Need help.
Formula: pixels = dips * (density / 160)
The Nexus 7 is 800x1280 with a 213 px density, which means it's resolution code is tvdpi (which means you can have a folder called drawable-tvdpi).
You can measure available screen size, minus window decorations, with:
this.getResources().getConfiguration().screenWidthDp;
this.getResources().getConfiguration().screenHeightDp;
On my N7, it returns 600 dp w, 888 dp h. Following the above formula, 888 dp height is 1280px - window decoration.
The Nexus7 is a unique device, with a somewhat strange dpi structure.
For nexus 7
layout-large-hdpi
Here is a very good explanation (from Dianne Hackborn - an Android engineer at Google): Dianne Hackborn explains the unique resolution of the Nexus7
Note: The app takes images from these folders only if you have not given higher precedence qualifiers. For example if you have given a layout folder like layout-sw360dp the app will take only the images from this folder even if you have given separate layouts like the one I said above. Because in android there is an order of precedence in which you have to give layouts.
Screen Density
Commonly referred to as dpi (dots per inch). Android groups all actual screen densities into four generalized densities: low (120), medium (160), high (240), and extra high (320). A device such as Galaxy Nexus has "extra high" screen density (more specifically, the dpi value is set at 320). The Nexus 7 uses "tvdpi" - i.e. 213 dpi.
Density Independent Pixel
Commonly referred to as dp. This is the virtual pixel unit used when displaying content. The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen. To calculate dp use the following formula:
px = dp * (dpi / 160)
or equivalently:
dp = (px / dpi) * 160
The reason Nexus 7 can show more content than the Galaxy Nexus despite having similar resolutions is this: the dpi of Nexus 7 is lower than Galaxy Nexus.
Galaxy Nexus (320 dpi, 720 pixels wide)
(720 / 320) * 160 = 360 dp
Nexus 7 (213 dpi, 800 pixels wide)
(800 / 213) * 160 = 600 dp
This means that when apps are rendering on the Galaxy Nexus, the width of the screen is actually 360 dp (rendered using 720 pixels). Whereas on the Nexus 7, the width of the screen is 600 dp (rendered using 800 pixels).
Try below code, give pixel value to below method it will give you result in dp.
public int convertSizeToDeviceDependent(int value) {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
return ((dm.densityDpi * value) / 160);
}
I'm developing an Android Widget and need to differentiate between Galaxy S and Galaxy S2.
I almost read everything about Screen sizes and densities articles.
And I need, of course, to use the new qualifiers with the new qualifier Smallest Width.
My problem is, that the sw320dp qualifier match for Galaxy S and also for Galaxy S2.
But I need another layout for Galaxy S2, but cant find the right qualifier for it.
Definition of Galaxy S, Density 233
Screen Size in Pixels: 480 Pixel x 800 Pixel
Screen Size in dp: 329dp x 549dp (cause 1dp = 1pixel/(density/160)
-> so the qualifier sw320dp must match here. and yes it does
Definition of Galaxy S II, Density 218
Screen Size in Pixels: 480 Pixel x 800 Pixel
Screen Size in dp: 352dp x 587dp (cause 1dp = 1pixel/(density/160)
-> so the qualifier sw340dp must match here, but NO it doesnt
(Tested in emulator and on real device)
The drawables are not the problem, but my layout, especially the height and text sizes are different on these devices, so I really need a specific layout for them.
Anyone has an idea or more experience with it?
Screen density, as defined by the reference material is:
The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch). For example, a "low" density screen has fewer pixels within a given physical area, compared to a "normal" or "high" density screen.
For simplicity, Android groups all actual screen densities into four generalized densities: low, medium, high, and extra high.
low = 120dpi
med = 160dpi
high = 240dpi
xhi = 320dpi
So the Galaxy SII, with a real density of 218, gets assigned a "high" density of 240 in dp calculations. Thus the width of the screen in dp is 480/240*160 = 320.
This sucks, I agree. But it's how it works.
http://developer.android.com/guide/practices/screens_support.html
I'm developing an Android Widget and need to differentiate between Galaxy S and Galaxy S2.
I almost read everything about Screen sizes and densities articles.
And I need, of course, to use the new qualifiers with the new qualifier Smallest Width.
My problem is, that the sw320dp qualifier match for Galaxy S and also for Galaxy S2.
But I need another layout for Galaxy S2, but cant find the right qualifier for it.
Definition of Galaxy S, Density 233
Screen Size in Pixels: 480 Pixel x 800 Pixel
Screen Size in dp: 329dp x 549dp (cause 1dp = 1pixel/(density/160)
-> so the qualifier sw320dp must match here. and yes it does
Definition of Galaxy S II, Density 218
Screen Size in Pixels: 480 Pixel x 800 Pixel
Screen Size in dp: 352dp x 587dp (cause 1dp = 1pixel/(density/160)
-> so the qualifier sw340dp must match here, but NO it doesnt
(Tested in emulator and on real device)
The drawables are not the problem, but my layout, especially the height and text sizes are different on these devices, so I really need a specific layout for them.
Anyone has an idea or more experience with it?
Screen density, as defined by the reference material is:
The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch). For example, a "low" density screen has fewer pixels within a given physical area, compared to a "normal" or "high" density screen.
For simplicity, Android groups all actual screen densities into four generalized densities: low, medium, high, and extra high.
low = 120dpi
med = 160dpi
high = 240dpi
xhi = 320dpi
So the Galaxy SII, with a real density of 218, gets assigned a "high" density of 240 in dp calculations. Thus the width of the screen in dp is 480/240*160 = 320.
This sucks, I agree. But it's how it works.
http://developer.android.com/guide/practices/screens_support.html
As the titles,the following is some arguments of the psd of my phone:
The width pixels:
The height pixels:
The width of document is:13.333 inch
The height of document is :7.5 inch
so the dpi will be 96,and we will know the phone is just a ldpi phone as the http://developer.android.com/guide/practices/screens_support.html
can anyone tell me whether it is right or not.
If your graphics are designed to display at 96 pixels/inch, then they are not a good match for Android. The minimum density devices are nominally 120 pixels/inch (called LDPI). If you put your graphics in res/drawable-ldpi, they will appear about 96/120 (or about 3/4) their original size (in inches).
If the images are displayed on a higher density device, Android will automatically scale the images up, so they will keep this size ratio regardless of actual device pixel density.
The only way to fix this is to rescale your images before adding them to yuor project. You will get the best quality if you rescale to each of the nominal pixel densities (120, 160, 240, and 320; you could also throw in 213 for tvdpi screens).