Size of android notification bar and title bar? - android

Is there a way to obtain the size of the notification bar and title bar in android? At the moment I obtain the display width and height with:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
After that I want to subtract the sizes of the bars so that I can stretch a video without losing aspect ratio. Currently I hide the bars because I can't see a better way.

Maybe this is a helpful approach: Referring to the Icon Design Guidelines there are only three different heights for the status (notification) bar depending on the screen density:
24px for LDPI
32px for MDPI
48px for HDPI
So if you retrieve the screen density of the device using densityDpi of DisplayMetrics you know which value to subtract
so it could look something like that:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int myHeight = 0;
switch (metrics.densityDpi) {
case DisplayMetrics.DENSITY_HIGH:
Log.i("display", "high");
myHeight = display.getHeight() - 48;
break;
case DisplayMetrics.DENSITY_MEDIUM:
Log.i("display", "medium/default");
myHeight = display.getHeight() - 32;
break;
case DisplayMetrics.DENSITY_LOW:
Log.i("display", "low");
myHeight = display.getHeight() - 24;
break;
default:
Log.i("display", "Unknown density");

*As for as I know, this works perfectly.
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}*

Martin's answer specified the wrong height (at least as of SDKv11). As per Icon Design Guidelines, the status bar icons have a height of 25dp, not 32dp. 25dp translates into these density-specific heights:
19px for LDPI
25px for MDPI
38px for HDPI
50px for XHDPI
An easy way to observe these sizes is to use the hierarchyviewer against an emulator or device with a normal density. Simply look at the value of getHeight() for the title bar's FrameLayout. The status bar is a bit trickier because it's part of the DecorView and not a view in itself, so get its height indirectly by looking at mTop for the title bar's FrameLayout, which is positioned immediately below the status bar. Per my observations the status bar and title bar each match the 25dp height of the status bar icons (I have not seen a declaration of this fact in the android ref as of SDKv11).

I use the following code for getting heights:
For Status (Notification) bar:
View decorView = getWindow().getDecorView();
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
For Title bar:
View contentView = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
int[] location = new int[2];
contentView.getLocationInWindow(location);
int titleBarHeight = location[1] - statusBarHeight;

hi i think that isn´t necessary and that will be automatically if you use a VideoView
VideoView vv = (VideoView) findViewById(R.id.MainVideo);
MediaController mc=new MediaController(this);
mc.setEnabled(true);
mc.show(0);
vv.setMediaController(mc);
vv.setVideoURI(Uri.parse(URLMedia));
vv.requestFocus();
vv.showContextMenu();
vv.start();

i have found a tutorial may be it would be helpful for u
helpful for me thou!
How to increase the size of the title bar in an Android application?
you can change your title bar size and the way you want it you can get it lucky chap !
have Fun

sorry for dummy comment, but that's no correct to use constants as height of notification bar.
just get the global view (PhoneWindow$DecorView) then get it's child (it'll be only one view (FrameLayout)). this layout contain You'r app views and measure whole screen (#see FrameLayout.mHeight). the first layout of it will be You'r first view, so getting the top of it will give You the right notification bar's height. Using FrameLayout without it's context will bring you nothing, cuz the top of you'r child will be equal to 0 in that case.
for lazy one's :
ViewGroup decoreView = (ViewGroup)*YourActivityViewHere*.getRootView();
int barSize = ((ViewGroup)decoreView.getChildAt(0)).getChildAt(0).getTop();
you can also use
getWindow().getDecorView().getRootView()
instead of YourActivityViewHere

This works waaaay better than hardcoding values because android will still return the value that would be the height of the status bar or action bar on that particular device even though they may not be visible.
So, the idea is to get the content view onto which all of your views are added.
public View getContentView(Activity a) {
int id = a.getResources().getIdentifier("content", "id", "android");
return a.findViewById(id);
}
Then, in your activity
View cView = getContentView(this);
cView.post(()->{
int offsetY = cView.getTop();
// do whatever here.
});
The good thing with the above code is that it'll also account for the action bar.

Related

Ho to get s8 useable screen android?

I am noob in android. My problem about useable height of 18:9 devices.
When I try to get useable screen in these aspect-ratio my application is woking fine all android devices but when ı compile in Samsung Galaxy s8 it is not working.
I am trying to get useable screen of devices.
I have already tried method which in these links
https://stackoverflow.com/questions/43628047/how-to-support-189-aspect-ratio-in-android-apps
https://android-developers.googleblog.com/2017/03/update-your-app-to-take-advantage-of.html
And I use dynamically
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
width = metrics.widthPixels;
height = metrics.heightPixels ;
And I tried
private int getSoftButtonsBarHeight() {
// getRealMetrics is only available with API 17 and +
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight)
return realHeight - usableHeight;
else
return 0;
}
return 0;
}
And when I try to set params MATCH_PARENT height it is working good. But I need to find useable height pixel to desing my other views proportionally .
Actually these code DisplayMetrics metrics = this.getResources().getDisplayMetrics();
height = metrics.heightPixels ; working in my Activity but when I try to use it in another window which I extend from FramaLayout and add to activity it is not working.
Here is my code block
public class StudentLoginActivity extends Activity { ...
FrameLayout.LayoutParams containerParams = new ScrollView.LayoutParams(width, height-sb);
container = new FrameLayout(this);
container.setLayoutParams(containerParams);
container.setBackgroundColor(Color.rgb(248,248,248));
loginStudentView = new StudentLoginView(this);
container.addView(loginStudentView); ...
}
public class StudentLoginView extends FrameLayout { ...
FrameLayout.LayoutParams cp = new FrameLayout.LayoutParams(width, height);
setLayoutParams(cp); ...
}
But this problem related with android navigationBar height because when I show navigation bar there is no problem but if I hide navigationBar it is not resize application still working that there is a navigation bar on screen (but I hide the navigationBar).
My problem is very similar this link
android Navigation Bar hiding and persantage of usable screen overlap
You can get the useable height (even on Galaxy S8 with or without shown NavBar) with the decorview:
//Get the correct screen size even if the device has a hideable navigation bar (e.g. the Samsung Galaxy S8)
View decorView = getWindow().getDecorView(); //if you use this in a fragment, use getActivity before getWindow()
Rect r = new Rect();
decorView.getWindowVisibleDisplayFrame(r);
int screenHeight = r.bottom; // =2220 on S8 with hidden NavBar and =2076 with enabled NavBar
int screenWidth = r.right; // =1080 on S8
If you have a view that is set to match the parent width and height (the whole screen), you can attach a listener to that view and then get its width and height.
View myView = findViewById(R.id.my_view);
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight,
int oldBottom) {
// its possible that the layout is not complete in which case
// we will get all zero values for the positions, so ignore the event
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
return;
}
// Do what you need to do with the height/width since they are now set
}
});
This answer was taken from here.

Get screen size in px on Android N with changed display zoom

I have a problem with the calculation of the display size on Android N with a changed display zoom.
With Android N you can change the display zoom (check here)
but the display size (...getSize()) doesn't change if the user sets a zoom from android settings...
Any idea to solve it? Have I to use the size in px multiplied by scaledDensity to have a real display size?
My app dinamically creates windows and components calculating screen dimensions in px, the components are designed on a server.
Briefly I do a math proportion by the width set on the server and the width of the smartphone screen :
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
display.getRealSize(sizePoint);
}else{
display.getSize(sizePoint);
}
int smartphoneDisplayWidth = sizePoint.x;
int smartphoneDisplayHeight = sizePoint.y;
int serverDisplayWidth = 720px; //this come from the server
int serverComponentWidth = 720px; //this come from the server
int smartphoneComponentWidth = (smartphoneDisplayWidth/serverDisplayWidth)*serverComponentWidth;
//ex: smartphoneComponentWidth = (1080/720)*720 = 1080; the component widht on the smartphone will be 1080px.
If i set a smaller zoom I have this problem:
default:
small:
the windows components are to small:
The width in px doesn't change, it changes only the density:
small
DisplayMetrics{density=2.2250001, width=1080, height=1813, scaledDensity=2.2250001, xdpi=422.03, ydpi=424.069}
default
DisplayMetrics{density=2.625, width=1080, height=1794, scaledDensity=2.625, xdpi=422.03, ydpi=424.069}
large
DisplayMetrics{density=2.875, width=1080, height=1782, scaledDensity=2.875, xdpi=422.03, ydpi=424.069}
larger
DisplayMetrics{density=3.125, width=1080, height=1770, scaledDensity=3.125, xdpi=422.03, ydpi=424.069}
largest
DisplayMetrics{density=3.375, width=1080, height=1758, scaledDensity=3.375, xdpi=422.03, ydpi=424.069}
You should create views using dp value instead of px. When density changes (like in nugat settings) you see the result in second screen.
Probably you create layout like this:
int screenWidth = <value>;
LayoutParams lp = new LayoutParams(screenWidth, 200);
view.setlayoutparams(lp);
You should use density:
float sampleDensity = 2f; // get from DisplayMetrics
int screenWidth = <value>;
LayoutParams lp = new LayoutParams((int) (screenWidth * sampleDensity), 200);
view.setlayoutparams(lp);
Other reason is maybe you not update layouts after configuration change. Better solution is use MATCH_PARENT and WRAP_CONTENT in LayoutParams. Its more convenient and fast solution.

Random TextView position

I'm trying to display a TextView in random positions on the screen, but the text shouldn't go outside the screen. The text will always be short, no more than 3 words. This is what I have so far:
final TextView tv = ((TextView)findViewById(R.id.text);
final Random rand = new Random();
final DisplayMetrics metrics = getResources().getDisplayMetrics();
int width = rand.nextInt(metrics.widthPixels);
int height = rand.nextInt(metrics.heightPixels);
final FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
flp.setMargins(width, height, 0, 0);
tv.setLayoutParams(flp);
UPDATE:
Forgot, I had this function to get a random number within a range:
public static int Random(final int lower, final int uppper)
{
return lower + (int)(Math.random() * ((uppper - lower) + 1));
}
So I updated the code to this:
int width = Random(0, metrics.widthPixels);
int height = Random(0, metrics.heightPixels);
But it still sometimes displays outside the viewing area. I even subtracted 10 from each value, to ensure it stays in. For the most part it does, but then it seems like it shows somewhere outside the screen.
try looking up abit more on getting the random number to stay inside the max width and height,
Why cant you do this?
Instead of doing that, you can found the Max x and Max y for the device and then Based on condition you can set the View's position to perticular position.
Also see this: SO
might be helpful to you.
comment me for any query.
but it still sometimes displays outside the viewing area
Dont you have title on top of your activity? That does count in... Am not sure but I think the notification bar as well... If u work in fullscreen mode, you shouldnt have problem.
Remember that the x y coordinates are always the upper left corner of an objectview! So it still can be happen that u get half (or full in case :D) of your picture/textview/whatever outside the screen...

Android: Get Screen size for the root Layout only

Please get me correctly over here :
I want to get the height/width of the space available to the Activity/Layout in onCreate() method to calculate the height that can be given to child layouts. I can get the screen size using :
root = (LinearLayout) findViewById(R.id.mainroot); // Main layout of LinearLayout
android.view.Display display = getWindowManager().getDefaultDisplay();
int height = Display.getHeight(); // I know this is deprecated have hence used
int width = Display.getWidth(); // DisplayMetrics
int childWidth, childHeight;
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
//int density = metrics.densityDpi;
height = metrics.heightPixels; //480
width = metrics.widthPixels; //320
This both the methods/ways gives me same height and width i.e. size of full screen. What I am looking for is to get actual height that is avaialbe for the layout after deduction of Application Title, Status Bar, etc.
Any idea how to get this. OR to get the sizes of titles, etc - what all should be counted over here. On emulator I see 2 bars on top - 1 must be application titile what an be the other one. I can get heights of them all and deduct from screen height.
ONE more point : In this case I will be setting the height programamtically so it will be pixel based (as I can setheight in pixels only I guess) will that affect in density factor with differnet screen sizes. What can be a way to calculate height (lets say 50%) for child layout that will be same for any density o so.
SOLUTION :
In my onCreate(), I added the following lines :
setContentView(R.layout.mainpage);
root = (LinearLayout) findViewById(R.id.mainroot);
root.post(new Runnable() {
public void run() {
Rect rect = new Rect();
Window win = getWindow();
win.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusHeight = rect.top;
int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
titleHeight = contentViewTop - statusHeight;
Log.i(Utility.TAG, "titleHeight = " + titleHeight + " statusHeight = " + statusHeight + " contentViewTop = " + contentViewTop);
// CALCULATE THE SIZE OF INNER LAYOUTS
calculateChildSize();
}
});
With the above code, I get the values of titleBar & statusBar. On deducting it from metrics.heightPixels; I get the required height of the screen.
Good Point is this code works for all density's.
Hope this helps others too.
FOR IMPROVEMENT : I have to do similar calculations for all Activities in my application, so was thinking about writing this code only once. I can save teh titleHeight to a static variable so can use in all activities.
BUT
Can the user change the phone's density at runtime.
If so, then the Activity's onCreate will be called again or not ?
If not, then can I trap the density change event where I can add this code and make the current activity to refresh.
Any idea suggestions for improving is appreciated.
//Where rootView is the object for the root view of your application
final int viewWidt = rootView.getMeasuredWidth();
There is very easy method for that. doOnLayout() method is called as soon as layout is measured and ready:
rootView.doOnLayout {
rootView.getMeasuredWidth()
rootView.getMeasuredHeight()
}

How to get available height in landscape?

I have a layout with an imageview. This imageview should have a 4/3 ratio. In portrait mode i get the width of the screen then compute the height and set the imageView dimensions.
int[] tailles = new int[2];
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int widthScreen = dm.widthPixels;
tailles[0] = widthScreen;
tailles[1] = (tailles[0]*3)/4;
This part works great.
In landscape mode i need to set the imageView width according to the available height. So i need to get the height of the screen minus the status/notification bar.
I saw the value of 48px for the bar in this question. Is it a standard size ?
What the best solution to get the available height regardless of the used device ?
Display d = ((Activity) mContext).getWindowManager()
.getDefaultDisplay();
int h = d.getHeight();
int w = d.getWidth();
in portrait h > w and in landscape w > h
If you're creating an Activity, than you have to have some sort of layout. Get it's root component, and retrieve it's size (getWidth, getHeight). That'll be the available width and height without counting the status bar.

Categories

Resources