Show and hide android notification bar without causing a layout jerk

Many android apps require toggling between full screen and non full screen view (lets call it framed screen) smoothly.
Typical apps which require this feature include social networking apps (which require maximum use of the space to accomodate infinite timeline like features), ebook reader apps, image gallery apps, video player etc.

By default, whenever you request for full screen mode, the activity will resize instantly to take the extra space and the this causes the child views to shift in position slightly to the top. This leads to a bad UX since the user does not expect the view to shift in position.

You can use the following method in your Activity to switch to full screen mode (which will hide the top notification bar)

Please note that some devices (like galaxy tab) dont have the top notification bar (a.k.a status bar), but have a navigation bar at the bottom which also acts like a notification/status bar. For such devices, there is no difference between full screen and framed screen modes. The navigation bar at the bottom can never be hidden. It can only be put into low profile mode, where the buttons turn into tiny dim dots. If you use the above code snippet to switch to fullscreen, the device will silently ignore the flags (no exceptions). Also you cannot make a generalisation about tablets not having a top notification bar, since devices like nexus 7 have both top and bottom bars. Be warned that there is no direct api to detect whether the device has a top bar and/or a bottom bar nor their heights. People have figured out a few hacks which rely on subtracting the app height from the device’s screen height to figure out things, but they are not very reliable. So do not try to write any code which makes any kind of assumption about the height of the bars.

In Mac OSX Lion GUI, fullscreen mode is handled in a clever way. Whenever a window goes into fullscreen mode, they crossfade between a snapshot of the windowed layout and a snapshot of the fullscreen. Doing the same in android would be a overkill, since the window resizes only by about 40dp, unlike mac where it could be commonly in the range of 100 – 1000 pixels width and height;

Let us go through some of the common methods we can use for a smooth transition between full screen and framed views in android.

FLAG_LAYOUT_NO_LIMITS | FLAG_LAYOUT_IN_SCREEN

For most apps this would be the easiest way of smooth transitioning. This flag basically lets android know that your layout should always take up all the available screen space (irrespective of the notification bar).

This means that the first child in your view group will start drawing from the top left of your screen (behind your notification bar). So switching between full screen and framed screen would not cause a resize and hence avoid a jerk. What you could do additionally is,specify a top padding of around 40 – 50 dp. Now, when you go fullscreen, you will see an empty space behind the notification bar which might work well for most applications.

The only problem with this approach is when you use honeycomb’s action bar (or its gingerbread backport called action bar sherlock).

Since you have specified that the application has no limits, action bar gets drawn behind the notification bar, which looks ugly since all your icons gets clipped at the top. A quick fix to this problem is to specify a top padding for your action bar.

This can be done using action bar styles. Refer this article which talks about theming action bar. Using this technique, you can specify android:paddingTop to around 40 dp which will draw some empty space to accomodate the notification bar. You will also need to increase the height of the action bar using android:height attribute.

This technique leads to 3 issues. One is that in tablets, the top padding looks bad. Since there is no accurate way to determine the height of the top notification bar, we cannot dynamically specify the padding. Some techniques which determine the height of notification bar return values like 48 dp even for devices which dont have a notification bar. The second issue is that, I noticed a bug in API > 11, where specifying a top padding acts like specifying both top margin and top padding, which means that it shifts the action bar downwards and also gives some extra space inside the action bar. Although this issue didnt occur in action bar sherlock (API<11) library. The third issue is that when the action bar has a drop down menu as the last visible item, the menu goes out of screen due the NO_LIMITS flag.

Gravity : Bottom

For some applications, this technique can be used to avoid the issues in the previous method. Using this method we let the layout get resized when the activity goes fullscreen, but at the same time, we specify that the child views have a gravity bottom and an absolute height. This means that when additional space becomes available due to removal of the notification bar, since the views are aligned to the bottom of the screen, no jerk occurs.

Be warned that if any of your views have the height set to match_parent, then a jerk can occur. For such views you should programmatically set the height to display.getHeight() in your onCreate and onConfigurationChanged method so that you have a view which takes most of the screen height.

The idea is to set the position of all views relative to the bottom of the screen because we know that the bottom of the screen will never change when we toggle between full screen and framed screen modes for any kind of device (be it galaxy tab or a galaxy nexus phone or a nexus 7 tab).

Animating resize

If you would like to animate any positional changes whenever the top bar hides, you could use the onSizeChanged method present in the view class. For e.g, you can create an empty custom view which has a height of “match_parent” and in the onSizeChanged method of this view, you can start your animation of other views. This will give a cool animation whenever the activity resizes.

This entry was posted by Kiran Kumar on February 10, 2013 at 11:15 pm, and is filed under Uncategorized. Follow any responses to this post through RSS 2.0. You can skip to the end and leave a response. Pinging is currently not allowed.

July 17th 2011 : Textoo Pro now in the apple app store. Download it here : http://textoo.in July 10th 2011 : Textoo v2.0 renamed to Textoo Pro Release of Textoo Pro has been postponed to July 15th 2011 due to app store codesign issues. Here’s a sneak peek into the brand new version of Textoo…

I just tried out the sencha touch examples on the android 1.6 simulator and the performance is pathetic. Seems like google forgot to properly implement their javascript V8 engine onto their OS. Appcelerator’s Titanium Mobile and Sencha touch are 2 different frameworks which address a totally different set of audiences. Comparing them is like comparing…

Hey there, My Name is Kiran Kumar (so is the name of this site) and I am a 23 yr old web developer from Mangalore, India. This blog is a place for me to share my thoughts and my contributions to the open source community. Apart from that, this website is my face on the…

Update : 17th July ’11 Textoo 1.0 is no more supported. Textoo Pro has reached the app store. Supports more gateways and has a lot of bonus features. Android version of Textoo is also being worked on. Click here to know more. Update : 22nd Sept ’10 A new page has been setup here for…