We will be playing with android's gorgeous new Material Design theme. We will be covering the following material widgets and animations that were introduced in Android 5.0 (API level 21).
- RecyclerView (the new ListView)
- CardView (custom outline and shadow)
- Ripple Animation (touch feedback)
- Palette (incorporate dynamic color)
- Shared Element Activity Transition
- Floating Action Button
- Circular Reveal Animation
Review Material Design Primer for a more detailed overview of all aspects of a material designed app.
Make sure you are working with a device or emulator running on API 21 or higher. While support libraries are available for material views and widgets, none of the animations would work on API versions lower than 21. Android introduced a dedicated render thread with API 21 for many of the Material Design animations, so they don't hold up the primary UI thread. At this moment it is not possible to work with Material Design animations on API versions lower than 21 due to the absence of this render thread.
- Import base app
-
The app loads a list of contacts into a
RecyclerViewwhere each list item is represented by aCardView. You will be building new features on top of this app. -
Clone android-lollipop-exercise repo on your machine. Import the project in Android Studio:
- Test your app
-
Test to verify that the app runs without any errors.
-
If your app loads successfully, you should see the following output:
- Understand existing code
- The app uses two new widgets that were introduced in API 21:
RecyclerViewandCardView. - Make sure you understand these concepts before moving forward.
- Refer to Using the RecyclerView cliffnotes for more information on
RecyclerView. - Refer to Using the CardView cliffnotes for detailed guide on using a
CardView.
- Hook up Detail View
- You will find
DetailsActivity.javaand it's layout fileactivity_details.xmlin your project to display more information about the contact selected from the list.- This activity is used to show contact's profile picture, name and phone number.
- The item click listener for the contacts list can be found inside the static internal class
VHofContactsAdapter.java. - Fire an intent when the user selects a contact from the list.
- Pass the contact through the intent and populate the detail view.
- Refer to the Using Intents to Create Flows cliffnotes for guidelines on passing data between activities.
- Test your app
-
If you run your app and click on a contact from the list, you should be able to view the detail view.
- Add Ripple Animation
- Add touch feedback animation, also called as 'ripple effect' to the
CardViewto provide visual effect to the user when an item in the list is touched. - Refer to the Adding Ripple Effect cliffnotes for guidelines.
- Read more about touch animations in Ripple Animations cliffnotes.
- Test your app
-
You should see the following output if you run your app now. Notice the ripple effect when you click on a list item.
- Use Palette
-
Use the new
PaletteAPI to extract the most vibrant color from the contact's profile image . -
Use this color to set the background color of the
R.id.vPaletteview containing contact's name inContactsActivityandDetailsActivity. -
The
PaletteAPI requires a bitmap of the image you want to extract the colors from as a parameter. You can usePicassoto get a callback with a bitmap, which can then be used to extract the most vibrant color from thePalette. -
In
ContactsAdapter.javaandDetailsActivity.java, you'll need to change the way the profile image is being loaded into theImageViewas follows:// Make sure to import this line at the top! import com.squareup.picasso.Target; // Use Picasso to get a callback with a Bitmap which can then // be used to extract a vibrant color from the Palette. // Define a listener for image loading Target target = new Target() { // Fires when Picasso finishes loading the bitmap for the target @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { // TODO 1. Insert the bitmap into the profile image view // TODO 2. Use generateAsync() method from the Palette API to get the vibrant color from the bitmap // Set the result as the background color for `R.id.vPalette` view containing the contact's name. } // Fires if bitmap fails to load @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }; // Store the target into the tag for the profile to ensure target isn't garbage collected prematurely holder.ivProfile.setTag(target); // Instruct Picasso to load the bitmap into the target defined above Picasso.with(mContext).load(contact.getThumbnailDrawable()).into(target);
-
See the Dynamic Color using Palette cliffnotes for guidelines on using the
PaletteAPI.
- Test your app
-
If you were able to successfully extract the vibrant color from the profile image using the
PaletteAPI to set the background color of your views, you should see the following output:
- Implement Shared Element Activity Transition
- A shared element transition determines how shared element views—also called hero views are animated from one activity to another during a scene transition. Shared element transitions are governed by changes to each shared element view's position, size, and appearance.
- Add shared element activity transition to provide a seamless experience by emphasizing continuity between activity transitions.
ContactsActivityandDetailsActivityshare three views:ivProfile,vPaletteandtvName.- Animate these three views while transitioning from
ContactsActivitytoDetailsActivityand vice versa. - Refer to the Shared Element Activity Transition cliffnotes for guidelines on implementing hero transitions.
- Test your app
- Add Floating Action Button
-
Add a floating action button to
DetailsActivityto dial a phone call to the selected contact. -
Floating action buttons are used for a special type of promoted action. They are distinguished by a circled icon floating above the UI.
-
The floating action button should be placed 16dp min from the edge on mobile and 24dp min on tablet/desktop.
-
Use the support libraries FloatingActionButton to add a button.
-
First, make sure that the library has been added to your
build.gradlefile. -
Next, add the custom
FloatingActionButtonview to youractivity_details.xmllayout file as follows:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> ... <FrameLayout xmlns:fab="http://schemas.android.com/apk/res-auto" android:layout_below="@+id/ivProfile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginTop="-50dp"> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:src="@drawable/ic_call" app:fabSize="normal" android:visibility="invisible" android:layout_gravity="bottom|right" android:layout_margin="16dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout> </RelativeLayout>
-
Extract the floating action button in your
DetailsActivity.javafile as follows:private FloatingActionButton fab; @Override protected void onCreate(Bundle savedInstanceState) { // ... fab = (FloatingActionButton) findViewById(R.id.fab); // ... }
-
See the floating action button guide for more details.
- Setup Click Listener
-
Setup a click listener on the fab button within your activity and dial the person's number on click of the button using an implicit intent.
@Override protected void onCreate(Bundle savedInstanceState) { // ... // Extract FAB fab = (FloatingActionButton) findViewById(R.id.fab); // Dial contact's number. // This shows the dialer with the number, allowing you to explicitly initiate the call. fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String uri = "tel:" + mContact.getNumber(); Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse(uri)); startActivity(intent); } }); // ... }
- Test your app
- Enable Up Button on
ActionBar
-
The navigation button or the up button appears in the
ActionBaralongside the activity title. -
In
DetailsActivity.java, enable up button by including below code:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_details); // Enable up button getSupportActionBar().setDisplayHomeAsUpEnabled(true); // ... }
- Add Circular Reveal Animation
-
Add circular reveal animation effect on the floating action button so that the button is revealed while entering the activity. Reverse this transition while exiting the activity.
-
When the activity starts, you would be revealing a previously invisible view. Hide your button in the
onCreate()method before starting the animation to make the animation look right.fab.setVisibility(View.INVISIBLE);
or in xml with
android:visibility="invisible"
-
Follow Circular Reveal Animation cliffnotes to add
enterReveal()andexitReveal()transitions on the floating action button. -
Make sure to enable exit reveal transition on press of
ActionBarup button or back button, callexitReveal()fromonOptionsItemSelected()andonBackPressed()as mentioned in the guide.
- Test your app







