When using the layout-swdp qualifiers I get the results as shown in the attachment. The sw qualifier is supposed to mean the smallest dimension must match or be bigger than the qualifier. This doesn't seem to work with the Nexus 7 (running 4.2.1). Am I confused about what smallest width qualifiers do or is the N7 reporting wrongly?
To reproduce my test case, I have many layout-swdp folders. Each has 2 textfield. The first just states which folders it's in. The next is the code below:
private CharSequence collectScreenStats() {
StringBuilder str = new StringBuilder();
DisplayMetrics metrics = getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
int dpWidth = (int)(width / metrics.density);
int dpHeight = (int)(height / metrics.density);
str.append(Build.MANUFACTURER);
str.append(" ");
str.append(Build.MODEL);
str.append("\n");
str.append("Pixels: ");
str.append(width);
str.append(" x " );
str.append(height);
str.append("\nDp (px / density): ");
str.append(dpWidth);
str.append("dp x " );
str.append(dpHeight);
str.append("dp" );
str.append("\nsmallest w: " + Math.min(dpWidth, dpHeight));
str.append("\ndensity: ");
str.append(metrics.density);
str.append("\ndensityDpi: ");
str.append(metrics.densityDpi);
return str;
}
Okay, this seems to be a bug in ICS where it doesn't accurate report the number of pixels of the entire screen as it taking into account the chrome.
Android DisplayMetrics returns incorrect screen size in pixels on ICS
So, my above display numbers are off as nexus 7 is 1280 x 800 and not 1280 x 736. Using the correct numbers, everything works.
Related
By magnifying the screen by "Settings / Displays", I've found that my galaxy s9+'s screen density changes to 430 dpi to somewhere over 600dpi.
This makes the layout and images to change to xxhdpi to xxxhdpi.
If I have a textView which has the fixed size of 16dp,
it was 16 * 3 px in xxhdpi, and will become 16 * 4 px in xxxhdpi.
This makes my layout(of course texts from editTexts or textViews) to become much bigger since the actual density of the device never changes, which google(or the maker samsumg) intended for this function.
But I do not want this to happen in my app.
I've tried to fix it by doing this ;
Configuration configuration = activity.getResources().getConfiguration();
if (configuration.densityDpi != 430) {
configuration.densityDpi = 430;
}
DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
WindowManager wm = (WindowManager) activity.getSystemService(activity.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.densityDpi * metrics.density;
activity.getResources().updateConfiguration(configuration, metrics);
This forces the screen density to become 430 and works fine on galaxy s9+.
But, as a matter of fact, the default density will not be 430 for all devices.
How can I figure out the default density of the device which runs my application?
Or is there a configuration to ignore the magnify effect for my application?
This seems to work for me.
DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
int snap = 20;
float exactDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2;
float dpi = displayMetrics.densityDpi;
if (dpi - exactDpi > snap) {
int targetDpi = (int) (Math.ceil(exactDpi / snap) * snap);
Configuration config = activity.getResources().getConfiguration();
ErrorController.showMessage("adjustDisplayScale : " + config.densityDpi);
ErrorController.showMessage("targetDpi : " + targetDpi);
displayMetrics.densityDpi = targetDpi;
config.densityDpi = targetDpi;
displayMetrics.setTo(displayMetrics);
config.setTo(config);
activity.getResources().updateConfiguration(config, displayMetrics);
}
For Android Tv, Android recommends Designing your artwork assets for best viewing at HD resolution (1920 x 1080 pixels).
There are following two available resolutions for TVs:
1280x720
1920x1080
Main two screen sizes available for android Tablets are 7 inch & 10 inch. This incurs in following two key resolutions(Considered from here):
7” tablets: 1024x600
10” tablets: 1280x800
Also, for different display devices we can have different resolution for Android TV devices and for tables for also.
I needs to calculate minimum readable textSize for each device for given message of given length.
Lets give me an example, User sets maximum message length to n chars. Now, I want to restrict user for this character length for specific device. So that i can have maximum length of message with minimum fontSize that is readable to users for all TV & tablet devices. It would be fine if we have lower limit, but maximum character limit should not make TextView scroll-able.
Initially I tried to calculate maximum message length as per fontSize of textview like following:
TextView text = (TextView) findViewById(R.id.text);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
int dens = dm.densityDpi;
double wi = (double) width / (double) dens;
double hi = (double) height / (double) dens;
double x = Math.pow(wi, 2);
double y = Math.pow(hi, 2);
double screenInches = Math.sqrt(x + y);
//long charLimit = (long) (Math.pow(Math.floor((dens / 18)), 2) * 2);
long charLimit = (long) (((Math.floor((dens / 26)) * wi) * (Math.floor((dens / 26)) * hi)) / (wi + hi));
//long charLimit = (long) ((Math.floor((dens / 22)) * Math.floor((x + y)) * 2));
String msg = "";
for (int i = 0; i < charLimit; i++) {
msg += "A";
}
text.setText(msg);
Log.e("screenInches", "screenInches: " + screenInches + " width:" + width + "/" + wi + " height:" + height + "/" + hi + " densityDpi:" + dens + " charLimit:" + charLimit);
But couldn't get satisfied results. Now,All what i want is to calculate minimum readable fontSize (say S), for given length(say n char) of message to be displayed without scroll on both Tv and tablet devices.
I know font-family and font-style also affects this. But considering system default configurations which are proper approaches, I should follow?
This is not possible to do very well with variable-width fonts. Each character I'm writing has a different width and this means each character's width has to be computed separately. A monospace font would be easier to compute.
I searched this question, and almost all of the answers are like this:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
But the official document says widthPixels is The absolute width of the display in pixels. I run the code above on my Nexus 5, and the width equals 1080. Obviously it is an Pixel value. Is there anything I missed? How can I get a dip value of the screen?
you should convert the result to dips, like:
private int pixelsToDips(int pixels)
{
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pixels / scale + 0.5f);
}
I have a problem which I`m unable to solve lately..
I have make a simple app for tablet which I run in my Samsung Galaxy Note 8.0 .. I have set the layout to place some text view at some place.. I code it in xml using dp for margin and sp for text size. The width and height layout is set to wrapcontent. But when I run it in my friend Samsung Galaxy Tab 2 7.0, the layout did not match what I see in my device. The same thing happen when I try to run it in 10inch emulator.
I have use layout-sw600dp for my layout folder..
Why my screen layout is like that?I though by using layout-sw600dp the layout supposedly to adjust itself.. Or am I wrong regarding that?
I have read android documentation regarding different screensize support and so far I found using layout-sw600dp is good solution..
I have checked the device dpi using :
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth = outMetrics.widthPixels / density;
Every device has different pixel ratio, different dpi, different screen size and so on. Go to this link, read it, you will know how to manage different device layouts.
Android - Supporting Multiple Screen
If you want to check the screen inch size when the app start, you can calculate the inch with the following two methods, but I think the second one is more precisely.
public static float getScreenInchSizeByDensityDpi(Context context) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
double x = Math.pow((double)dm.widthPixels / (double)dm.densityDpi, 2);
double y = Math.pow((double)dm.heightPixels / (double)dm.densityDpi, 2);
double screenInches = Math.sqrt(x + y);
return (float) screenInches;
}
public static float getScreenInchSizeByXYDpi(Context context) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
double x = Math.pow((double)dm.widthPixels / (double)dm.xdpi, 2);
double y = Math.pow((double)dm.heightPixels / (double)dm.ydpi, 2);
double screenInches = Math.sqrt(x + y);
return (float) screenInches;
}
I am working to get device display diagonal length. I used the formula, diagonal = width* width + height* height. To achieve this I use below code.
DisplayInfo aDisplayInfo = new DisplayInfo();
DecimalFormat twoDecimalForm = new DecimalFormat("#.##");
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
aDisplayInfo.widthInch = (dm.widthPixels * dm.density) / (dm.xdpi * 2);
aDisplayInfo.heightInch = ((dm.heightPixels * dm.density) / (dm.ydpi * 2));
aDisplayInfo.widthPix = dm.widthPixels;
aDisplayInfo.heightPix = dm.heightPixels;
// approaach 1
aDisplayInfo.diagonalInch = twoDecimalForm.format(Math.sqrt(Math.pow(
aDisplayInfo.widthInch, 2)
+ Math.pow(aDisplayInfo.heightInch, 2)));
After running this code I found out different results in different devices. Like:
Samsung Galaxy S3 = 4.8 inches (correct)
HTC One X = 6.8 inches (wrong) [ will be 4.7 inches]
What's wrong with this code? Any kind of help will be appreciated.
Try this:
aDisplayInfo.widthInch = dm.widthPixels / dm.xdpi;
aDisplayInfo.heightInch = dm.heightPixels / dm.ydpi;
widthPixels/heightPixels should be the physical pixel count. xdpi/ydpi should be pixels per inch. You shouldn't need to do any scaling on these values.