Update 2/20/2014: Due to a few issues, the app formally known as PikShare has been renamed LensRocket. Everything except some names remains the exact same as the originally released source code and application.
Update: At the time of writing, this seemed to work fine on the multiple devices I had tested on. However, by the time I launched the app, I started seeing issues with the one device I had running KitKat. Let that serve as a reminder to test your apps on every device and OS version you can and test as soon as a new version is released.
While working on the Android version of LensRocket, I ran into a pretty big smoothness issue. Specifically, when you go from a full screen activity to a non-full screen activity, there can be an issue related to the ActionBar appearing underneath the notification bar as the notification bar slides down. Unless you’re currently running into this exact issue, that might be hard to picture. Thankfully, I' put together a little animation for you to check out:
As you can see, when the button is tapped, the RocketsListActivity slides in from the left. When it does so, the notification bar starts sliding down at the same time. Since when the activity first starts sliding in, the notification bar isn’t there, it’s displayed at the top of the screen. Once the notification bar finishes it’s slide down, the action bar is then “shoved” down (or it jumps down or bounces down or is pushed down, whatever you prefer). This looks pretty terrible and would certainly not be part of any polished app. Fixing this didn’t was far from easy to figure out, however, the solution ends up being “fairly” simple.
Styling the ActionBar
The first step in fixing this was something I had already set up while working on this app which was customizing the style of the ActionBar. If you create a new Android project you’ll end up with a styles.xml file which has some values by default (at least as of several versions of the ADT ago) and looks like this:
This gives you a place to override the default styles of your application. In this case it’s overriding the Theme.Light theme. In order to override the appearance of our ActionBar, we’ll use this styles file. To start doing so, we just need to drop this into the AppTheme style:
<item name="android:actionBarStyle">@style/ActionBarStyle</item>
This says that we want to override the style of our ActionBar’s with a new style called ActionBarStyle. In the case of the above application, that style looks like this:
The specifics here don’t matter too much. We’re setting a few colors and then pointing the titleTextStyle at an additional style. In order to solve our problem, we need to add one more element to this style:
<item name="android:layout_marginTop">12dp</item>
Oddly enough, as of writing, if you try to autocomplete the layout_marginTop name value, it doesn’t show up as an option. This initially lead me to believe that it wasn’t a valid attribute. Testing would prove otherwise. Essentially, putting this value in means that our action bar will have a margin above it (in this case a margin of 12dp). Doing this and rerunning our app gives us something that looks like this:
So now we know that the margin works. Unfortunately, things still look terrible. Thankfully, the last step is equally easy!
Setting Window Flags
The problem we have is that our screen still has to adjust when the ActionBar gets to the bottom of it’s slide down. Wouldn’t it be ideal if we could tell our content view to ignore the notification bar. As luck would have it, we can! To do so, open up the onCreate method of the activity that will show the notification bar and action bar (so in the case above, PiksListActivity). Prior to setting the content view, we need to get access to the window object and add flags to it. Specifically, the flags for FLAG_LAYOUT_IN_SCREEN and FLAG_LAYOUT_NO_LIMITS:
Once we’ve done that and run again, we get something much better that looks like this:
Basically we’ve set some flags that told our view to use the full screen and ignore anything else on the screen (i.e the notification bar). Once we’ve done that, our view will ignore the notification bar and not reposition itself when the notification bar finishes sliding down. Observant people will see a bit of white between the action bar and the notification bar as they slide together. I would just fix this by setting the background of the view to be black to match the notification bar and it wouldn’t look as weird.
Summary
Now you should know how to handle making a nice smooth transition from full screen to a non-full screened activity. This can be a little easier if you’re not using an action bar (you’d just put a top padding on your content view) but it should be pretty easy to handle regardless of what you’re doing now. Let me know if you have any questions!
5 Comments
John Dow
Thanks, great explanation!
Chris
Hope it helped!
luizje
Why don't you clear those flags instead of setting them with padding?
Chris
The problem I see when doing that is that there is a black bar that appears very briefly right below the status bar. After the new activity (the piks or friends list) slides in, that bar disappears and everything looks fine. However, for that brief moment, it doesn't look right. Any ideas?
Adam
Thanks! This will help me but what if your second view was not white? What I found this animation is a pain..