When you view the screen of an app in Google Play, that’s exactly what you see–a meaningful transition from image to app bar, which happens as a response to user input–scrolling down. This particular transition is called a parallax effect, and this blog post will show you how to add it to your application.
The Android 5.0 Lollipop release–the most significant Android release ever–introduced Material Design, which refreshed the entire Android experience. An important part of the Material Design is the Responsive Interaction. It encourages deeper exploration of an app by creating timely, logical and delightful reactions to user input. Another important aspect is the use of meaningful transitions between view states in a way that presents the information according to what is most important for the user right now. One way to do this is by using the parallax effect.
Here, we will demonstrate the Parallax effect using a list of items, shown in groups by Telerik ListView for Android.
We are going to use Android Studio for this post, but the same idea can be applied within your preferred IDE. Create a new app and add the aar files necessary for the ListView, part of Telerik UI for Android, to the libs folder of your application (the files are Common, Data and List). Then, add the following dependencies to your app’s build.gradle file:
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:recyclerview-v7:22.2.1'
compile 'com.android.support:design:22.2.1'
compile(name: 'Common', ext: 'aar')
compile(name: 'Data', ext: 'aar')
compile(name: 'List', ext: 'aar')
<
android.support.design.widget.CoordinatorLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
xmlns:app
=
"http://schemas.android.com/apk/res-auto"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:fitsSystemWindows
=
"true"
>
…
</
android.support.design.widget.CoordinatorLayout
>
For many of the features of material designs app bar concepts, namely scrolling gestures, the Design Library provides the AppBarLayout. It depends heavily on being a direct child of the coordinator layout, so we'll add it as a direct child to the layout that we just added:
…
<
android.support.design.widget.AppBarLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"240dp"
android:fitsSystemWindows
=
"true"
android:theme
=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
>
…
</
android.support.design.widget.AppBarLayout
>
…
…
<
com.telerik.widget.list.RadListView
android:id
=
"@+id/myList"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
app:layout_behavior
=
"@string/appbar_scrolling_view_behavior"
/>
…
…
<
android.support.design.widget.CollapsingToolbarLayout
android:id
=
"@+id/collapsing_toolbar_layout"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:fitsSystemWindows
=
"true"
app:contentScrim
=
"?attr/colorPrimary"
app:layout_scrollFlags
=
"scroll|exitUntilCollapsed"
>
…
</
android.support.design.widget.CollapsingToolbarLayout
>
…
…
<
ImageView
android:contentDescription
=
"@string/content_description"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:fitsSystemWindows
=
"true"
android:scaleType
=
"centerCrop"
android:src
=
"@drawable/telerik"
app:layout_collapseMode
=
"parallax"
/>
<
android.support.v7.widget.Toolbar
android:id
=
"@+id/toolbar"
android:layout_width
=
"match_parent"
android:layout_height
=
"?attr/actionBarSize"
app:layout_collapseMode
=
"pin"
app:popupTheme
=
"@style/ThemeOverlay.AppCompat.Light"
/>
…
These views should define their layout_collapseMode-s so they respond in accordance with the CollapsingToolbarLayout’s events. The value pin means the Toolbar will remain pinned, while the parallax value for the ImageView speaks for itself.
Now let’s go the code for the activity using this layout. We will need a few lines to set up the toolbar as a support action bar:
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
ActionBar actionbar = getSupportActionBar();
if
(actionbar !=
null
) {
actionbar.setDisplayHomeAsUpEnabled(
true
);
}
RadListView listView = (RadListView)findViewById(R.id.myList);
ListViewDataSourceAdapter adapter =
new
ListViewDataSourceAdapter(getData());
adapter.addGroupDescriptor(
new
Function<Object, Object>() {
@Override
public
Object apply(Object
object
) {
Entity entity = (Entity)
object
;
return
entity.category;
}
});
listView.setAdapter(adapter);