An important note when managing different screen height
With such fragmented devices variants Android has, Android provide the capability of supporting variants of screens (e.g. different resolution, sizes) by enabling developer to define its resources value in different folder representing the supported variants.
The commonly used is the resolution. And I also commonly take care of the favorite Samsung Galaxy SII devices that has 320dp width (i.e. differs from most other that has 360dp or wider). We could easily archive that be defining the dimens in respective folder i.e.
values-w320dp, value-w360dp… etc.
Managing Different Height
Of late, I came across a need to handle different height.
Obviously Samsung Galaxy SII has is shorter (533.33dp) compare to Samsung Galaxy S7 (640dp).
But there are some devices does varies e.g. Nexus 5, although physically has the height of 640dp, but has 48dp of it has been used by the System Bar (at the bottom for Soft Button). Hence it essentially has 592dp.
Nicely we could easily programmatically calculate them
Float deviceDensity = getResources().getDisplayMetrics().density;
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
float deviceHeight = outMetrics.heightPixels / deviceDensity;
float deviceWidth = outMetrics.widthPixels / deviceDensity;
This will return 640dp for Samsung Galaxy S7 and 592dp for Nexus 5. Great, we could now define the respective value folders for what we need.
Separating the folders
Seems easy, we could have the below folders, and put the respective dimens within it.
values-h533dp, value-h592dp, value-h640dp… etc.
To my amazement, nothing works! It doesn’t take the value defined in the respective folder at all! I tried rename the folders by add and minus 1–5dp, though some rounding issue but still doesn’t work. Is this a bug in Android!!? :(
The important note
After some investigation, now all is clear and logical. Apparently it was stated in developer.android.com.
The Android system might use some of the screen for system UI (such as the system bar at the bottom of the screen or the status bar at the top), so some of the screen might not be available for your layout
The status bar! We should exclude the status bar height for the height number we use to name the folder. In the case of Nexus 5, the 592dp height includes the Status Bar height (which is 25dp). Hence the number we should define in your folder is 592–25 = 567dp.
So if we define the value folder as below, the Nexus 5 would be able to get the respective value defined in this folder.
value-h567dp — Nexus 5
Do note, not all status bar is 25dp. For Samsung Galaxy S7 and Samsung Galaxy Note II, it is 24dp. For Samsung Note II, it is 25dp tough.
value-h509dp — Samsung Galaxy SII
value-h615dp — Samsung Galaxy Note II
value-h616dp — Samsung Galaxy S7 (it will use h615dp if there’s no h616dp)
This stackoverflow share that some are 19dp and 38dp etc.
To verify for a specific device, you could get my code and run it. To be safe, you could assume a slightly bigger number status bar, as device will pick the folder name with a smaller number that is closest to it (i.e. Samsung Galaxy S7 will use h615dp).
One thing that bothers my mind is, the above snippet of code calculating the height, does remove the System Bar from the calculation, but not the Status Bar. Maybe because one could use the Status Bar area for its view. This can be done with the below code in onCreate()
With or without this code, the height calculation still return the same (include the status bar height), and it is still referring to the same resource folder (with the number that shouldn’t include the status bar height), even though the actual height of the App used differs. Some slight imperfection from Google :P