I have an image that is the background of one activity in my app.
For the Samsung Galaxy S4 this image should be 1920x1080 and placed at the xxhdpi folder.
For the Nexus 10 this image should be 2560x1600 and placed at the xhdpi folder.
It's nonsense to place an image bigger in the xhpdi folder than an image placed at the xxhdpi folder.
And because that I believe that I misunderstood something.
Can someone explain what I misunderstood?
--edit--
For all the answer questioning if the nexus10 is really xhdpi and the S4 xxhdpi:
The answer of prijupaul is good, but I don't have any Nexus 10 or Galaxy S4 to test. I discovered the resolution trying to create AVDs for both, in the device configuration creation it says what configuration it one will be.
The resource classes 'hdpi', 'xhdpi' and 'xxhdpi' have nothing to do with resolution (width and height in plain pixels) but everything to do with density (number of pixels per inch of screen).
The S4 has a lower resolution but can have a higher density because it screen is smaller.
I think it is quite well explained in the documentation (developer.android.com). Check that for more details.
You should then use another qualifier than xhdpi if resolution does really matter. You can use for example drawable-sw720dp (targets 10" tablets).
My personal opinion though is that you should just have a version for each aspect ratio in the biggest size. Then compute that aspect ratio at runtime and pick the best image from assets.
Isnt S4 is xhdpi? Did you verify using
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int density = dm.densityDpi;
switch(density)
{
case DisplayMetrics.DENSITY_LOW:
Toast.makeText(context, "ldpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_MEDIUM:
Toast.makeText(context, "mdpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_HIGH:
Toast.makeText(context, "hdpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_XHIGH:
Toast.makeText(context, "xhdpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_XXHIGH:
Toast.makeText(context, "xxhdpi", Toast.LENGTH_SHORT).show();
break;
}
This does not answer the question. But, This could will be useful to double check it again.
I think it's about to 'PPI'. Galaxy s4 has 441 ppi but Nexus 10 has 300 ppi.
Are you sure image for nexus10 should be in xhdpi folder?
Nexus10 has 300ppi,which is different to dip.
Visit Android XXHDPI resources
It should be like this,
s4:xhdpi
nexus10:xxhdpi
Related
I am working on a Xamarin.Forms app and I need to identify the android screen/resolution is whether small, medium or large to adjust some content with the available space. For example, some labels (single line) are getting truncated in smaller devices. So I could make some adjustments if the resolution is smaller or not.
In iOS, when iPhone screen getting bigger, the resolution is also getting increased so it's easy to identify smaller resolution devices in iOS. But in android, this seems hard.
Android device resolution can be taken from
var resolutionH = Resources.DisplayMetrics.HeightPixels;
var resolutionW = Resources.DisplayMetrics.WidthPixels;
For testing, I have created the following emulators and run the app in them. Here's my result whether a label getting truncated or not.
Resolution Density Result
---------------------------
2560x1440 560 OK
1920x1080 400 OK
1280x720 320 Truncated
1280x720 280 OK
1280x720 240 OK
800x480 240 Truncated
800x480 160 OK
The problem here is a device with higher resolution and lower DPI won't cause any problem. Like a device with 1280x720 resolution and 240 DPI (or 280 DPI). Since there are tons of Android devices are available with different resolutions and densities this problem seems harder.
Is there a better way to categorized android devices (small, medium, and large)?
The reason where a label's text getting truncated (in my case) or an element doesn't get enough space in a particular device is, the actual pixel calculation for an element using the density (dpi/ppi) and the density bucket that screen falls into. This article gives a good idea about calculating the physical size of an element for different display densities.
After some exhausting research, I was able to categorize the device screen by taking the combination of screen width pixels and density. (I got the data from Android developer website Distribution dashboard and Support different screen sizes)
I have categorized the screen width pixels into 4 categories and then calculated the screen size for each display density using following formula:
sqrt((widthPixels x widthPixels) + (heightPixels x heightPixels)) / density
Then I have searched in the GSMArena to find devices with the screen configurations in the above table. Screen size lower than 3 inches is mostly smartwatches and more than 8 inches could be Tabs and smart TVs. So I have taken devices with the screen size between 3 - 8 inches as mobile devices (smartphones).
What you are looking for is easy to do in native android you can create a method and check for the DensityMetricsDensity something like below:
private string GetDeviceDensity()
{
var density = Resources.DisplayMetrics.DensityDpi;
switch (density)
{
case DisplayMetricsDensity.Medium:
return "MDPI";
case DisplayMetricsDensity.High:
return "HDPI";
case DisplayMetricsDensity.Low:
return "LDPI";
case DisplayMetricsDensity.Xhigh:
return "XHDPI";
case DisplayMetricsDensity.Tv:
return "TV";
case DisplayMetricsDensity.Xxhigh:
return "XXHDPI";
case DisplayMetricsDensity.Xxxhigh:
return "XXXHDPI";
default:
return "Unknown";
}
}
I have an app with different versions for screens (small, normal, largue, and extraLargue XML files) each with its XML designed for each type, but I found a Huawei phone with this screen 3.5" HVGA 320x480.
My question is, should not the UI of Android use the small configuration for this screen? Is that the app when running on this phone uses the normal configuration as if it were a nexus4 4.7" 768x1280 as I change that?
I tried to create various types of screen (create other) with multiple configurations without optimal result.
Assuming the 3.5" measurement is on the diagonal, this works out to about 165 dpi which falls into the mdpi (or normal screen size) bucket according to Android's Supporting Multiple Screens guide.
DPI = sqrt(w^2 + h^2) / d
where
w is the width of the display in pixels
h is the height of the display in pixels
d is the physical diagonal measurement of the display in inches
It is quite simple.
You need to add different UI and make controls VISIBILE and GONE.
int appScreen = getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
switch(appScreen) {
case Configuration.SCREENLAYOUT_SIZE_LARGE:
UIControl.setVisibility(View.GONE);
break;
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
UIControl.setVisibility(View.GONE);
break;
case Configuration.SCREENLAYOUT_SIZE_SMALL:
UIControl.setVisibility(View.GONE);
break;
default:
UIControl.setVisibility(View.GONE);
}
is there any resources, such as tables or calculators, related to android devices, available on the mapping between physical screen dimensions (in inches) and their typical density independent pixel (dp) count? for example, what is the typical dp count on screens of sizes for 3.5 / 4 / 7 / 10.1 inches? this is handy as, in terms of size variations, most devices falls on one of the aforementioned dimensions (like 4 inches for phones and 7 inches for tablets) and it may probably help others too if such mapping exists. thanks in advance!
There is a website which collects information about viewport sizes (i. e. sizes in dp) of different devices:
http://viewportsizes.com/
Most phones have 320 and 360 dp width in portrait orientation, most 7" tablets have shortest width 600 dp in portrait orientation, most 10" tablets have shortest width 720 dp.
you can differentiate between device via device's status bar height,
`int resId = getResources().getIdentifier("status_bar_height", "dimen",
"android");
if (resId > 0) {
}
switch (getResources().getDimensionPixelSize(resId)) {
case 25: // small screen
break;
case 50:// for galaxy s3's status bar height
break;
case 75:
break;
case 38:
break;
default:
`
and here is the link , its gives you all information about display of all type of devices.
http://www.emirweb.com/ScreenDeviceStatistics.php
hope your problem got the solution.
Your Total Screen DP is Device Width * (dpi).
DPI varies based on Device Density. its 1 pixels for MDPI devices and so on. You can calculate the same for height as well for all devices. U can find online sites to do this calculation
The one I use is :
Angry Tools
You can find what you need and more in Material Design.
I've noticed that real device picks up different resource from that eclipse shows in preview.
For example I created drawable resources for devices with smallest width of 720dp as
drawable-sw720dp-mdpi for Samsung Galaxy Tab 1280x800 mdpi
drawable-sw720dp-hdpi for Nexus 10 2560x1600 hdpi.
But Samsung Galaxy Tab 1280x800 mdpi picks up the drawable-sw720dp-hdpi instead of drawable-sw720dp-mdpi ?
Same thing with other devices. If there are resources drawable-sw320dp-hdpi, drawable-sw320dp-xhdpi, the Sony Ericsson xperia-ARC 854x480 hdpi picks up drawable-sw320dp-xhdpi ?
I cant just keep drawable-hdpi resource because there are devices 5'5 inch screen size. For example samsung galaxy 1280x720 hdpi 5'5 inch, and for such devices there is different graphical design so both devices 854x480 hdpi and 1280x720 hdpi will be using the same directory drawable-hdpi wich is not acceptable.
Any ideas?
Some time ago I had similar problem, while writing animated wallpaper which was using canvas and bitmaps. I couldn't achieve what I wanted using default layout folders.
In my case, for example, medium density device with xlarge screen (1280x800), should use the same resources as high density with normal screen (600x1024).
I've decided to write my own solution, by putting resources into three groups and selecting them using custom rules.
DisplayMetrics metrics = resources.getDisplayMetrics();
int screenSize = resources.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
switch (metrics.densityDpi) {
case DisplayMetrics.DENSITY_LOW:
if (screenSize == Configuration.SCREENLAYOUT_SIZE_SMALL || screenSize == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
return new SmallResourceProvider(resources);
}
case DisplayMetrics.DENSITY_MEDIUM:
if (screenSize == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
return new MediumResourceProvider(resources);
}
default:
return new LargeResourceProvider(resources);
}
Maybe this will be helpful in your case.
I was also facing the same strange issue. In my case Galaxy tab GT P7500 was picking images from drawable-sw720dp-XXHDPI folder as i had the XXHDPI folder also. If i deleted the XXHDPI, it picks up the next lower which is the XHDPI folder.
The issue is with the swxxxdp qualifier for drawable folders. If i remove the screen width and use just 1 set of images of all densities the issue seems to be resolved. However i wanted to have different set of drawables for 7 inch and 10 inch devices. What i did was use a different set of names for the 10 inch images and 7 inch images and use 2 different set of layouts with sw600dp and sw720dp qualifiers.
Here is my current structure which works well. However this is not the expected way of using the resources, as android recommends externalizing the drawables. unfortunately i couldn't find a better solution.
layout-land
layout-sw600dp-land (uses image.png)
layout-sw720dp-land (image_large.png)
and for drawables,
drawble-mdpi (image.png & image_large.png)
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
I am working on an android application. i have used different layout folder. Like layout,layout-large,layout-xlarge. So that it can adjust for all resolutions. But i am setting images dynamically in activity. How can i change them according to screen resolution? How too big image will replace smaller if we change resolution?
Android works with density buckets, which go from l(low)dpi to xx(extra extra)h(high)dpi.
You want to create different versions of your images in folders as
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
and drawable-xxhdpi if you want to support the Nexus 10.
That's kind of loose from the layout-large folders, which enable you to define different layouts for different sizes.
2 pretty different things, which you can read much more about at
screen practices in Android.
=======
Edit; Seems this wasn't exactly the question.
If you're doing it 'the right way' the Android system will choose the correct image for you, even when adding them dynamically (you can still call R.drawable.my_image from java code).
If for some reason you do have to choose, you can simply check for the current density with something like (a little outdated);
public String getDensity() {
String density;
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// will either be DENSITY_LOW (120) , DENSITY_MEDIUM (160) or
// DENSITY_HIGH (240)
switch (dm.densityDpi) {
case 120:
density = "ldpi";
break;
case 160:
density = "mdpi";
break;
case 240:
density = "hdpi";
break;
// use hdpi as default, because flurry shows this will be suited for
// most of our users.
default:
density = "hdpi";
break;
}
return density;
}