I created some custom elements, and I want to programmatically place them to the upper right corner (n
pixels from the top edge and m
pixels from the right edge). Therefore I need to get the screen width and screen height and then set position:
int px = screenWidth - m;
int py = screenHeight - n;
How do I get screenWidth
and screenHeight
in the main Activity?
getMetrics
. Nik's comment in his answer even explains getDisplayMetrics
to consider the system/status bar size. Also you may use density as jmaculate and LoungeKatt explained to have the EXACT value:DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;
Tested in Android v2.2 (API 8) and v4.0 with good results and no errors/warnings. - anyone Resources.getSystem().getDisplayMetrics()
. You won't need a Context
to get them. - anyone For API Level 30, WindowMetrics.getBounds
is to be used. An example of its usage can be found in the linked docs:
final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
// Gets all excluding insets
final WindowInsets windowInsets = metrics.getWindowInsets();
Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
| WindowInsets.Type.displayCutout());
int insetsWidth = insets.right + insets.left;
int insetsHeight = insets.top + insets.bottom;
// Legacy size that Display#getSize reports
final Rect bounds = metrics.getBounds();
final Size legacySize = new Size(bounds.width() - insetsWidth,
bounds.height() - insetsHeight);
Old answer:
If you want the display dimensions in pixels you can use getSize
:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
If you're not in an Activity
you can get the default Display
via WINDOW_SERVICE
:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
If you are in a fragment and want to acomplish this just use Activity.WindowManager (in Xamarin.Android) or getActivity().getWindowManager() (in java).
Before getSize
was introduced (in API level 13), you could use the getWidth
and getHeight
methods that are now deprecated:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // deprecated
int height = display.getHeight(); // deprecated
For the use case, you're describing, however, a margin/padding in the layout seems more appropriate.
Another way is: DisplayMetrics
A structure describing general information about a display, such as its size, density, and font scaling. To access the DisplayMetrics members, initialize an object like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
We can use widthPixels
to get information for:
"The absolute width of the display in pixels."
Example:
Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
Answered 2023-09-21 08:07:10
try/catch
for such a check? Why not simply use if (android.os.Build.VERSION.SDK_INT >= 13)
without any thrown exception at all? I think of try/catch
in a normal app-flow as bad practice. - anyone One way is:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
It is deprecated, and you should try the following code instead. The first two lines of code gives you the DisplayMetrics
objecs. This objects contains the fields like heightPixels
, widthPixels
.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
Api level 30 update
final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
// Gets all excluding insets
final WindowInsets windowInsets = metrics.getWindowInsets();
Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
| WindowInsets.Type.displayCutout());
int insetsWidth = insets.right + insets.left;
int insetsHeight = insets.top + insets.bottom;
// Legacy size that Display#getSize reports
final Rect bounds = metrics.getBounds();
final Size legacySize = new Size(bounds.width() - insetsWidth,
bounds.height() - insetsHeight);
Answered 2023-09-21 08:07:10
It may not answer your question, but it could be useful to know (I was looking for it myself when I came to this question) that if you need a View's dimension but your code is being executed when its layout has not been laid out yet (for example in onCreate()
) you can setup a ViewTreeObserver.OnGlobalLayoutListener
with View.getViewTreeObserver().addOnGlobalLayoutListener()
and put the relevant code that needs the view's dimension there. The listener's callback will be called when the layout will have been laid out.
Answered 2023-09-21 08:07:10
View.post()
isn't guaranteed to work? I'm curious because I also rely on this method for getting a View's size after layout and was unaware it unreliable. - anyone View
you get the ViewTreeObserver
from? Or do they all share the same one? - anyone (2012 answer, may be out of date) If you want to support pre Honeycomb, you will need to put in backward compatibility prior to API 13. Something like:
int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
Point size = new Point();
w.getDefaultDisplay().getSize(size);
measuredWidth = size.x;
measuredHeight = size.y;
} else {
Display d = w.getDefaultDisplay();
measuredWidth = d.getWidth();
measuredHeight = d.getHeight();
}
Of course the deprecated methods will eventually be taken out of the the most recent SDKs, but while we still rely on most of our users having Android 2.1, 2.2 and 2.3, this is what we are left with.
Answered 2023-09-21 08:07:10
I have tried all possible "solutions" unsuccessfully and I noticed that Elliott Hughes' "Dalvik Explorer" app always shows correct dimension on any Android device/OS version. I ended up looking at his open source project that can be found here: https://code.google.com/p/enh/
Here's all the relevant code:
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
// used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
// used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}
EDIT: slightly improved version (avoid firing exceptions on non-supported OS version):
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}
Answered 2023-09-21 08:07:10
Simplest way:
int screenHeight = getResources().getDisplayMetrics().heightPixels;
int screenWidth = getResources().getDisplayMetrics().widthPixels;
Answered 2023-09-21 08:07:10
For accessing the height of the status bar for Android devices, we prefer a programmatic way to get it:
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = getResources().getDimensionPixelSize(resId);
}
The variable result
gives the height in the pixel.
For more information about height of Title bar
, Navigation bar
and Content View
, kindly look on Android Device Screen Sizes.
Answered 2023-09-21 08:07:10
getResources().getDisplayMetrics().heightPixels + result
gives actual fullscreen height. Dragan Marjanović's answer also works but I prefer this much shorter and simpler solution. - anyone OnApplyWindowInsetsListener
. - anyone First get view (eg. by findViewById()
) and then you can use getWidth() on the view itself.
Answered 2023-09-21 08:07:10
I have two functions, one for sending the context and the other getting height and width in pixels:
public static int getWidth(Context mContext){
int width=0;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(Build.VERSION.SDK_INT>12){
Point size = new Point();
display.getSize(size);
width = size.x;
}
else{
width = display.getWidth(); // Deprecated
}
return width;
}
and
public static int getHeight(Context mContext){
int height=0;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(Build.VERSION.SDK_INT>12){
Point size = new Point();
display.getSize(size);
height = size.y;
}
else{
height = display.getHeight(); // Deprecated
}
return height;
}
Answered 2023-09-21 08:07:10
@SuppressLint("NewApi")
just above the function signature in order to be able to compile. - anyone For dynamically scaling using XML there is an attribute called "android:layout_weight"
The below example, modified from synic's response on this thread, shows a button that takes up 75% of the screen (weight = .25) and a text view taking up the remaining 25% of the screen (weight = .75).
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text="somebutton">
<TextView android:layout_width="fill_parent"
android:layout_height="Wrap_content"
android:layout_weight=".75">
</LinearLayout>
Answered 2023-09-21 08:07:10
This is the code I use for the task:
// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
display.getSize(screen);
} else {
screen.x = display.getWidth();
screen.y = display.getHeight();
}
Seems clean enough and yet, takes care of the deprecation.
Answered 2023-09-21 08:07:10
Isn't this a much better solution? DisplayMetrics comes with everything you need and works from API 1.
public void getScreenInfo(){
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
heightPixels = metrics.heightPixels;
widthPixels = metrics.widthPixels;
density = metrics.density;
densityDpi = metrics.densityDpi;
}
You can also get the actual display (including screen decors, such as Status Bar or software navigation bar) using getRealMetrics, but this works on 17+ only.
Am I missing something?
Answered 2023-09-21 08:07:10
Just adding to Francesco's answer. The other observer that is more apt, if you want to find out the location in window or location in screen is ViewTreeObserver.OnPreDrawListener()
This also can be used to find other attributes of a view that is mostly unknown at onCreate() time e.g. the scrolled position, the scaled position.
Answered 2023-09-21 08:07:10
Find width and height of the screen:
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
Using this, we can get the latest and above SDK 13.
// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
Point size = new Point();
display.getSize(size);
width = size.x;
Log.i("width", "if =>" +width);
}
else {
width = display.getWidth();
Log.i("width", "else =>" +width);
}
Answered 2023-09-21 08:07:10
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Answered 2023-09-21 08:07:10
Using the following code in Activity.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Answered 2023-09-21 08:07:10
Need to say, that if you are not in Activity
, but in View
(or have variable of View
type in your scope), there is not need to use WINDOW_SERVICE
. Then you can use at least two ways.
First:
DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();
Second:
DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);
All this methods we call here is not deprecated.
Answered 2023-09-21 08:07:10
This is not an answer for the OP, as he wanted the display dimensions in real pixels. I wanted the dimensions in "device-independent-pixels", and putting together answers from here https://stackoverflow.com/a/17880012/253938 and here https://stackoverflow.com/a/6656774/253938 I came up with this:
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
Answered 2023-09-21 08:07:10
public class AndroidScreenActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
String str_ScreenSize = "The Android Screen is: "
+ dm.widthPixels
+ " x "
+ dm.heightPixels;
TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
mScreenSize.setText(str_ScreenSize);
}
}
Answered 2023-09-21 08:07:10
For getting the screen dimensions use display metrices
DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null)
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display defaultDisplay = windowManager.getDefaultDisplay();
defaultDisplay.getRealMetrics(displayMetrics);
}
Get the height and width in pixels
int width =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
Answered 2023-09-21 08:07:10
I found this did the trick.
Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Answered 2023-09-21 08:07:10
You can do get the height size using :
getResources().getDisplayMetrics().heightPixels;
and the width size using
getResources().getDisplayMetrics().widthPixels;
Answered 2023-09-21 08:07:10
There is a non-deprecated way to do this using DisplayMetrics (API 1), that avoids the try/catch messiness:
// initialize the DisplayMetrics object
DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();
// populate the DisplayMetrics object with the display characteristics
getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);
// get the width and height
screenWidth = deviceDisplayMetrics.widthPixels;
screenHeight = deviceDisplayMetrics.heightPixels;
Answered 2023-09-21 08:07:10
I would wrap the getSize code like this:
@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
Point size = new Point();
Display d = a.getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
d.getSize(size);
} else {
size.x = d.getWidth();
size.y = d.getHeight();
}
return size;
}
Answered 2023-09-21 08:07:10
For who is searching for usable screen dimension without Status Bar and Action Bar (also thanks to Swapnil's answer):
DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
screen_h -= getResources().getDimensionPixelSize(resId);
}
TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}
Answered 2023-09-21 08:07:10
fun getScreenHeight(activity: Activity): Int {
val metrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(metrics)
return metrics.heightPixels
}
fun getScreenWidth(activity: Activity): Int {
val metrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(metrics)
return metrics.widthPixels
}
Answered 2023-09-21 08:07:10
Resources.getSystem().displayMetrics.heightPixels
- anyone First load the XML file and then write this code:
setContentView(R.layout.main);
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());
Show width and height according your screen resolution.
Answered 2023-09-21 08:07:10
Follow the methods below:
public static int getWidthScreen(Context context) {
return getDisplayMetrics(context).widthPixels;
}
public static int getHeightScreen(Context context) {
return getDisplayMetrics(context).heightPixels;
}
private static DisplayMetrics getDisplayMetrics(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics;
}
Answered 2023-09-21 08:07:10
There are times when you need to know the precise dimensions of the available space for a layout when in an activity's onCreate. After some thought I worked out this way of doing it.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivityForResult(new Intent(this, Measure.class), 1);
// Return without setting the layout, that will be done in onActivityResult.
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
// Probably can never happen, but just in case.
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
int width = data.getIntExtra("Width", -1);
// Width is now set to the precise available width, and a layout can now be created. ...
}
}
public final class Measure extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create a LinearLayout with a MeasureFrameLayout in it.
// Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
LinearLayout linearLayout = new LinearLayout(this);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
measureFrameLayout.setLayoutParams(matchParent);
linearLayout.addView(measureFrameLayout);
this.addContentView(linearLayout, matchParent);
// measureFrameLayout will now request this second activity to finish, sending back the width.
}
class MeasureFrameLayout extends FrameLayout {
boolean finished = false;
public MeasureFrameLayout(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (finished) {
return;
}
finished = true;
// Send the width back as the result.
Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
Measure.this.setResult(Activity.RESULT_OK, data);
// Tell this activity to finish, so the result is passed back.
Measure.this.finish();
}
}
}
If for some reason you don't want to add another activity to the Android manifest, you can do it this way:
public class MainActivity extends Activity {
static Activity measuringActivity;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras == null) {
extras = new Bundle();
}
int width = extras.getInt("Width", -2);
if (width == -2) {
// First time in, just start another copy of this activity.
extras.putInt("Width", -1);
startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
// Return without setting the layout, that will be done in onActivityResult.
return;
}
if (width == -1) {
// Second time in, here is where the measurement takes place.
// Create a LinearLayout with a MeasureFrameLayout in it.
// Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
measureFrameLayout.setLayoutParams(matchParent);
linearLayout.addView(measureFrameLayout);
this.addContentView(linearLayout, matchParent);
// measureFrameLayout will now request this second activity to finish, sending back the width.
}
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
// Probably can never happen, but just in case.
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
int width = data.getIntExtra("Width", -3);
// Width is now set to the precise available width, and a layout can now be created.
...
}
class MeasureFrameLayout extends FrameLayout {
boolean finished = false;
public MeasureFrameLayout(Context context) {
super(context);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (finished) {
return;
}
finished = true;
// Send the width back as the result.
Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
// Tell the (second) activity to finish.
MainActivity.measuringActivity.finish();
}
}
Answered 2023-09-21 08:07:10
Much simpler in Kotlin.
val displayMetrics = Resources.getSystem().displayMetrics
displayMetrics.heightPixels
displayMetrics.widthPixels
Answered 2023-09-21 08:07:10
Resources.getSystem
if you wanna make sure this one suits your purpose. - anyone