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);
}
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";
}
}
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 thought I was successful in adjusting for different screen sizes(I was using the eclipse emulators and creating different screen sizes to test my app) but when I test my app on actual devices the result of my app varies. for example for a large screen size I set my emulator to a Nexus S and it will work and look fine, but then I try on an Alcatel One Touch Fierce(real device) which is still considered a large screen size the app play is just a little bit off, then I play it on another device which is also considered a large screen size the app will play just like the emulator. So i guess mt question is why? a samble of how I'm checking for different screen sizes is below:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
switch(displayMetrics.densityDpi)
{
case DisplayMetrics.DENSITY_LOW:
// layout for small sized devices.
break;
case DisplayMetrics.DENSITY_MEDIUM:
// layout for medium-sized devices.
break;
case DisplayMetrics.DENSITY_HIGH:
// layout for large devices.
break;
case DisplayMetrics.DENSITY_XHIGH:
// layout for really large devices.
break;
Before your case statement, try to print the density value like this:
Log.i("Sushil", "displaymetrics.densityDpi : " + displaymetrics.densityDpi);
And check if it matches with any of your defined case statement. Else add new case statements, it should work. Few more defined cases are :
DisplayMetrics.DENSITY_TV
DisplayMetrics.DENSITY_XXHIGH
Hope this helps.
i don't see any thing wrong with the outcomes. if you run an app designed on a phone emulator-----on a tablet, the layouts will not match.
you have to decide if you wanna support different screen sizes or not if you do, then you'd have to create diffrent layouts for different screen sizes and set the corresponding layout in the OnCreate method of your Activity.
here is how to check if the device is a tablet or a phone:
if(isTablet==true){
setContentView(R.Layout.my_tablet_layout);
}else{
setContentView(R.Layout.my_phone_layout);
}
public boolean IsTablet() {
return (getApplicationContext().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
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;
}
All the different resolutions of the different Android products are driving me nuts.
My first android app that I wrote was designed so it supported the three commonly used resolutions: 240x320 (LDPI), 320x480 (MDPI) and 480x800 (HDPI). The 480x854 didn't do any harm to the layout because it has the same width as 480x800.
I've also bought the following devices to test my android apps on:
Samsung Galaxy Europe (LDPI)
HTC Desire Z (HDPI)
Luckily my girlfriend has a HTC Wildfire S (MDPI) so I've got most resolutions covered.
But today, my brother downloaded my app on his new HTC Sensation which has yet another resolution 540x960 (HDPI?). Which didn't show my app as it should and probably the most tablets won't show it correctly either.
What I've did with my first app was read out the density and then set the parameters:
public void set_ui_parameters() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
if(metrics.densityDpi == DisplayMetrics.DENSITY_HIGH){
textSize = 35;
timeWidth = 80;
dayWidth = 110;
moneyWidth = 50;
} else if(metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM){
textSize = 35;
timeWidth = 53;
dayWidth = 73;
moneyWidth = 33;
} else if(metrics.densityDpi == DisplayMetrics.DENSITY_LOW){
textSize = 28;
timeWidth = 40;
dayWidth = 55;
moneyWidth = 25;
}
}
Besides the parameters I've also created drawables for LDPI, MDPI and HDPI. This works fine for the resolutions described above, but this depends on the screen resolution i.c.w. screen size and fails for, for example the HTC sensatoin with 540x960.
I know that not all the resolutions are used that often, but I would like to support as many as possible. Stats of Screen Sizes and Densities
I've read Supporting Multiple Screens multiple times but didn't found a clear answer to this "problem".
So should I read out the resolution and set the parameters according to the resolutions instead of density? Is this a smart thing to do or how do you cope with this?
Thanks a lot for your information!
You don't have to do that to support different densities. What you do is create different resources folders:
res/values-ldpi/dimens.xml
res/values-mdpi/dimens.xml
res/values-hdpi/dimens.xml
Then Android will decide which file to use. You can have something like:
<!-- in values-ldpi/dimens.xml -->
<dimen name="textSize">25dip</dimen>
and..
<!-- in values-mdpi/dimens.xml -->
<dimen name="textSize">20dip</dimen>
etc. And you shouldn't care about resolution... there are a lot of different resolutions sizes so it would be a hell to take decisions based on that.
Also, if you use dp instead of pixels, you hardly ever will have to create different dimensions files for each density. Of course, sometimes you have to, but it depends on the app.
Only thing you have to do is, that you set android:minSdkVersion to 7 or higher in your manifest file. Is is possible that some views will appear slightly different but app is
applicable and on whole screen.
Now, i'm just guessing here since the rest of the implementation isn't shown, but I'm assuming you are using those derived measurements as px
Take a look at dp. That essentially does all those things you did, automatically, for any device. (Device Independent Pixel)
Don't worry about the slight difference in resolution: 540x960 is only slightly bigger than 480x800. The extra vertical space is easy: it gives you more room for your lists. For horizontal space, as long as you're handling your layouts correctly you'll simply have extra padding (30pix ea) on the sides.
Unfortunately, full-width images (480 wide) are a slightly bigger problem. If you want pixel perfect images, you'll want to use scaleType="center" so the image centers but not scales. If you want full width, you can use scaleType="fitCenter" to make it fill. It will be a bit fuzzy... but so many thing on Android are ;-)
I ran into this problem as well, except my app is a game where there is one SurfaceView canvas that I draw background images and sprites to (similar to LunarLander example).
The way you handle it here is to extend your background image to the largest size you are willing to support (540x960) but you keep all the important things (like buttons, text, information, etc) within a smaller rectangle of 480x800. You can extend the image itself, or just add borders. The key is that nothing important is there.
People with 480x800 phones will see your normal app. People with 540x960 phones will see a little extra border.