Using Parallax for Fun And Profit
The idea of a parallax is to give the illusion of depth thanks to targets seemingly moving at a different pace. You have probably already noticed the effect in real life when riding on a straight line e.g. staring at individual scenery items from a train window.
The idea is basically that the closer an object is to you, the faster it seems to move to your eyes. The extreme being the background (like distant mountains) which doesn’t seem to move at all.
This effect, called Parallax, is used proficiently on iOS and Android launchers when scrolling through your apps to make it look like your wallpaper is further away from your icons as they move.
We can re-create parallax pretty easily on Android using the ViewPager
class of the support package as a foundation for handling the touch events and displaying our content.
Our goal here is to create an awesome on-boarding screen to present your app. Each “slides” will have its own background and a couple of visual elements (text, device frame, other widgets) that will be arranged in different virtual layer (i.e. some will move faster than others).
Check out an example below of such a screen and the slightly different position offsets applied to each elements:
The core idea is to setup a ViewPager
taking up all the screen space (you can even use the new KitKat translucent window chrome like in the screencast with the Holo.*.NoActionBar.Translucent
style) and then create a generic FrameLayout
-based layout (remember how FrameLayout is your friend?) for the page. You don’t need to add an ImageView
for the background since we will directly use the background property of the FrameLayout
.
It’s also not necessary to have pre-scaled those background images since setting them as the background drawable of the main FrameLayout
will automatically make them fit but it’s better if their dimensions are close to the form factor of the device (16/9 portrait usually) so that they don’t appear squashed (if you want to get fancy you might want to dynamically blur those too).
Afterwards, just sprinkle the layout with TextView
, ImageView
or whatever other view you may want to showcase your app using the layout_gravity
and layout_margin
attributes to align them on the screen. Here is the example, very dumb, layout I’m using for the demo:
Once you have wired your ViewPager
with an Adapter feeding the right content, we are going to create a PageTransformer which is where the parallax magic is gonna be created. Implementing this interface requires only one method which is called for every scroll offset of a given page View
together with a value indicating its position relative to the center of the screen.
That relative position is very handy because it’s clamped between -1 (left of the screen) and +1 (right of the screen) with the zero value in the middle. That means we can derive a very simple parallax equation based on its value:
The trick is then to have a way to define layers and then let the user supply a couple of arguments to parametrize the effect. In the above class, we achieve this by letting the user gives a list of view IDs for each layer they want to create. You can then set the instance on your ViewPager
by calling the SetPageTransformer
method.
As a final piece of information, know that this technique only work on Android 3.0+ because ViewPager
assumes you are using animatable properties.