This may end up being a "yes" or "no" question...
Starting in Nougat (maybe marshmallow?), users can change the display size of their device. Specifically on the Galaxy S8 and S8+, the user can change the display resolution.
I've seen the solutions here: Get Screen width and height
QUESTION: Do these solutions give the actual height/width of the screen regardless of changed resolution or do they give the adjusted height/width of the screen if resolution changed?
If the first, how do I get the adjusted height/width?
Interesting question. It gives me adjusted dimensions in pixels. I have tested it now in my Pixel running Android O.
Method 1:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
Method 2:
Configuration configuration = getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp;
int screenHeightDp = configuration.screenHeightDp;
int smallestScreenWidthDp = configuration.smallestScreenWidthDp;
Both methods returned the adjusted dimensions. The first method returns the device screen dimensions. The second method returns the dimensions of the app screen. These two result would vary when there are two apps open in multi-window mode.
Related
Has anyone noticed this issue and resolved the way of getting the absolute display size consistently in both orientations?
Example, Nexus 5 (5.0.1):
Portrait: width = 1080 height = 1776
Landscape: width = 1794 height = 1080
I would have thought that the height in portrait would match the width in landscape. Initially suspected the status bar, but docs are clear. Anyway the status bar height in this example is 75px in either orientation and the diff in the example is 18px.
Code snippet for display width and height in pixels:
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
String dimensions = String.format("width = %d height = %d", width, height);
Log.v(TAG, dimensions);
Assuming the display is FullHD acording to your logging there's something of 144px (48dp) height in portrait and 126px (42dp) width in landscape occupying the display (when scaling factor is 3 which is xxhdpi). I bet it's the navigation bar with Back, Home and Recent buttons. This is sufficient for choosing layouts.
EDIT:
If you need the full display size the following code is available from API 17:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
if (Build.VERSION.SDK_INT >= 17) {
display.getRealSize(size);
} else {
display.getSize(size); // correct for devices with hardware navigation buttons
}
EDIT2:
If you want to make sure you get correct result on API 14 through 16 consider following this answer along with its comments
https://stackoverflow.com/a/11004877/2444099 .
It's not the entire screen size, its the size of the UI that display metrics gives you. You have to factor in the amount of screen size taken up by the area taken up by the status bar (clock, battery level, signal strength bar) which will differ on orientation.
I have an ImageView with matchParent property in width.
how can i know its runtime width on my device (using eclipse, without adding code programmatically)?
how can I know the conversion ratio between dpi to pxls in my device?
I have an ImageView ... how can i know its runtime width on my device
You can get the width when the ImageView is measured, i.e. later than the runtime. However you can get the screen's width and height like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
And if for example your ImageView takes up a specific portion of your screen you can measure it using the screen's width and height.
how can I know the conversion ratio between dpi to pxls in my device?
To convert say 20 pixels to DP do (adding to the above code):
int dp = 20 / metrics.density:
Extra: Here's a dpi to pixel calculator
If you don't want to use the TreeObserverListener way, you can try to get the View to measure itself and give you what the dimensions would be if it were calculated. In my experience, this has worked in most cases but not all; especially if the View is in some special dynamic layout or the ordering of the hierarchy prevents the dimensions from being calculated in the correct order. You might find luck in refering to this popular answer.
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
screen_width = display.getWidth();
screen_height = display.getHeight();
I understand that the code above could drive me to get the screen width and height. I put this code in "onCreate" of "MainActivity".
But my friend's mobile device could not show the desired layout. Yet, it is too trouble for me to debug in his mobile device. Thus, I look forward to the help here.
My Question is ...
Is it right to get the width and height in "onCreate"?
Is it useful to get the width and height of all devices? (of course, API>=11)
Yes it's right to get the Screen Height and width in onCreate() method because if your Screen rotates then your onCreate will be called. and it's not mandatory that you should take Screen Height & width if needed OK or else you can manage it in Xml as well. To get Screen height and width i think this is the best way...
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
for more details you use this link as well
http://developer.android.com/reference/android/view/Display.html
You could try metrics instead:
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
int displayHeight = metrics.heightPixels;
int displayWidth = metrics.widthPixels;
Doing it in onCreate should be fine.
But honestly, I don't think you are really getting the wrong height and width. The screen size is probably just very different from your test devices.
You will need to debug with his phone at least once to find out what the problem is.
In my opinion it is a good approach to get the width and height, because it gives you more control. Most layout stuff could be done by working with proper layouts (eg LinearLayouts with weight), but there are cases where doing it manually will work better. You can do things more precisely, but it will be more work.
Also if you don't have a large variety of devices for testing it will be tough to adjust it properly. Just think about all the different sizes the Android world can confront you with. I for example had some problems with very small devices, like a Galaxy Mini. Also very big devices like tablets might be a problem. Theres just no way around testing edgecases if you want to do it manually.
I am developing an Android app that is causing me problems with devices that have 1024 as their width dimension. I have tried creating a layout folder layout-w1024 and layout-mdpi-sw1024dp; but the device uses the layout-mdpi folder instead. I am using 15 as the minimum android version.
Is there any other way using which I can separate 1024 devices?
You can do it programmatically if it's suitable for your project, something like this would call a different layout depending on the dimensions of the screen. This has some limitations though since it can only be called from an Activity (shouldn't be a problem in your case) and if you have problems with layouts all over your application it may not be very scalable.
The conditional width == 1024 should probably be replaced with something greater than or more specific, you'll need to play with this for a while to make it work. You should also account for the height of the screen, not only the width.
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
Or if you want it in pixels instead:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
And then:
//Depending on the width, set one layout or anotherone
setContentView(width == 1024?R.layout.for1024:R.layout.normal);
Source
I am new to Android. I like having the free range of drawing objects where ever I want. So i have been using Absolute Layout. I get a message saying to use a different layout. And I have read that this is because of the different res of different phones. My question is, is this the only reason in not using Absolute Layout? I have made a method that uses metrics to adjust the pixels.
public int widthRatio(double ratioIn){
DisplayMetrics dm = new DisplayMetrics(); //gets screen properties
getWindowManager().getDefaultDisplay().getMetrics(dm);
double screenWidth = dm.widthPixels; //gets screen height
double ratio = screenWidth/100; //gets the ratio in terms of %
int displayWidth = (int)(ratio*ratioIn); //multiplies ratio desired % of screen
return displayWidth;
}
//method to get height or Ypos that is a one size fits all
public int heightRatio(double ratioIn){
DisplayMetrics dm = new DisplayMetrics(); //gets screen properties
getWindowManager().getDefaultDisplay().getMetrics(dm);
double screenHeight = dm.heightPixels; //gets screen height
double ratio = screenHeight/100; //gets the ratio in terms of %
int newHeight = (int)(ratio*ratioIn); //multiplies ratio by desired % of screen
return newHeight;
}
//sets size of any view (button, text, ...) to a one size fits all screens
public void setSizeByRatio(View object, int width, int height){
LayoutParams params = object.getLayoutParams();
params.width = widthRatio(width);
params.height = heightRatio(height);
}
So if i say setSizeByRatio(Button, 10, 25); It will set the buttons width to 10% of the width of the screen and the height to 25% percent of the screen.
Are there any phones that Absolute Layouts do not work on? Does this layout cause any other issues?
The reason why the AbsoluteLayout is deprecated is because you have alternatives in the LinearLayout or the GridLayout that does the same and more. It seems that you are trying to calculate positions based on absolute positions and number of pixels, an approach that should in general be avoided due to issues with varoius screen sizes and densities.
Read the link that #amiekuser provided and focus on the understanding how the best practice is. Some hints are creating images for ldpi, mdpi and hdpi folders, using the unit for dpi (density independent pixels) instead of raw pixels and how to test your app on multiple screen sizes and densities using the emulator.
Edit:
To set the x- and y-position of a View you must use LayoutParams. See this question on how to to set the TopMargin and LeftMargin for a View using LayoutParams.
Android phones comes in many form factors i.e. not only it varies greatly in terms of screen size(2.7", 3.2", 3.7" ....) but also in terms of resolution (480X800, 480X848 etc).
Google itself suggest not to use AbsoluteLayout. in fact its deprecated in the newer api versions.
The link below explains all these in details:
http://developer.android.com/guide/practices/screens_support.html
Check the best practices section.