6

How can I get the available height of the screen in Android? I need to the height minus the status bar / menu bar or any other decorations that might be on screen and I need it to work for all devices. Also, I need to know this in the onCreate function. I know this question has been asked before but I have already tried their solutions and none of them work. Here are some of the things I have tried:

This does not take into account the status bar / menu bar:

Display display = getWindowManager().getDefaultDisplay(); screenWidth = display.getWidth(); screenHeight = display.getHeight(); 

Neither does this:

Point size = new Point(); getWindowManager().getDefaultDisplay().getSize(size); screenWidth = size.x; screenHeight = size.y; 

Nor this:

Point size = new Point(); getWindowManager().getDefaultDisplay().getRealSize(size); screenWidth = size.x; screenHeight = size.y; 

This does not work:

Display display = getWindowManager().getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); display.getMetrics(metrics); // since SDK_INT = 1; screenWidth = metrics.widthPixels; screenHeight = metrics.heightPixels; try { // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar) screenWidth = (Integer) Display.class.getMethod("getRawWidth").invoke(display); screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display); } catch (Exception ignored) { // Do nothing } try { // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar) Point realSize = new Point(); Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize); screenWidth = realSize.x; screenHeight = realSize.y; } catch (Exception ignored) { // Do nothing } 

I then used the following code to subtract the height of the status bar and menu bar from the screen height:

int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) result = getResources().getDimensionPixelSize(resourceId); screenHeight -= result; result = 0; if (screenHeight >= screenWidth) resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); else resourceId = getResources().getIdentifier("navigation_bar_height_landscape", "dimen", "android"); if (resourceId > 0) result = getResources().getDimensionPixelSize(resourceId); screenHeight -= result; 

On API 17 it gives it correctly calculates the height of the status bar and menu bar in portrait but not in landscape. On API 10, it returns 0. I need it to work ideally on all devices or minimum API 10.

3

3 Answers 3

0

Have you tried doing your height calculations in onWindowFocusChanged of the Activity class? This eliminates API troubles by calculating what you really want, not messing with menu bars etc.

@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT); screenHeight=content.getHeight(); } 
Sign up to request clarification or add additional context in comments.

4 Comments

I have not tried this but it will only work if it is called before OnCreate.
Just for my own education, which methods or commands are you using that need to be complete before onCreate? In my own solution, I was able to move a lot of the functionality from onCreate to onWindosFocusChange and things appeared correctly once the screen ddisplayed for the user.
I simply need to get the correct screen height and width before or during OnCreate so that I can give my objects the correct size and position. I have it working. See my solution. Also, your code won't work because OnCreate is being called first. Thanks anyway for your help
I'm glad you have what you need! Thanks for working through it with me!
0

Here is how I managed to get the correct screen dimensions for all devices:

public class MainActivity extends Activity { static int ScreenWidth; static int ScreenHeight; static int ScreenWidthLandscape; static int ScreenHeightLandscape; private RelativeLayout layout; private RelativeLayout.LayoutParams params; private View top; private View bottom; @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); layout = new RelativeLayout(this); top = new View(this); bottom = new View(this); RelativeLayout.LayoutParams viewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); viewParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); top.setLayoutParams(viewParams); viewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); viewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); bottom.setLayoutParams(viewParams); layout.addView(top); layout.addView(bottom); setContentView(layout); final Intent intent = new Intent(this, myPackage.learnSpanishVerbs.Start.class); final View view = getWindow().getDecorView().getRootView(); ViewTreeObserver vto = view.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int topLoc[] = new int[2]; top.getLocationOnScreen(topLoc); int BottomLoc[] = new int[2]; bottom.getLocationOnScreen(BottomLoc); boolean portrait = getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE; if (portrait) { ScreenWidth = top.getWidth(); ScreenHeight = BottomLoc[1] - topLoc[1]; } else { ScreenWidthLandscape = top.getWidth(); ScreenHeightLandscape = BottomLoc[1] - topLoc[1]; } if (Build.VERSION.SDK_INT < 16) view.getViewTreeObserver().removeGlobalOnLayoutListener(this); else view.getViewTreeObserver().removeOnGlobalLayoutListener(this); startActivity(intent); finish(); } }); } } 

1 Comment

Do you really need those top and bottom views? Isn't it enough to have a layout spanning the whole screen and just get its height in onGlobalLayout?
0

The best solution I have managed to come up with is this:

Display display = getWindowManager().getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); display.getMetrics(metrics); screenWidth = metrics.widthPixels; screenHeight = metrics.heightPixels; TypedValue tv = new TypedValue(); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) screenHeight -= TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); } int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) screenHeight -= getResources().getDimensionPixelSize(resourceId); 

I have tested it on API 7 - 17. Unfortunately, on API 13 there is extra space at bottom both horizontally and vertically and on API 10, 8, and 7 there is not enough space at the bottom both horizontally and vertically. (I have not tested on obsolete APIs).

1 Comment

were you able to find a solution to this ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.