Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koalahamlet/04cebf2d7f6ba01f22bd to your computer and use it in GitHub Desktop.
Save koalahamlet/04cebf2d7f6ba01f22bd to your computer and use it in GitHub Desktop.

Hacking in a material world

Challenge

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).

Review Material Design Primer for a more detailed overview of all aspects of a material designed app.

Prerequisites

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.

  1. Import base app
  • The app loads a list of contacts into a RecyclerView where each list item is represented by a CardView. 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:

  1. Test your app
  • Test to verify that the app runs without any errors.

  • If your app loads successfully, you should see the following output:

  1. Understand existing code
  • The app uses two new widgets that were introduced in API 21: RecyclerView and CardView.
  • 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.
  1. Hook up Detail View
  • You will find DetailsActivity.java and it's layout file activity_details.xml in 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 VH of ContactsAdapter.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.
  1. 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.

  1. Add Ripple Animation
  • Add touch feedback animation, also called as 'ripple effect' to the CardView to 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.
  1. 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.

  1. Use Palette
  • Use the new Palette API to extract the most vibrant color from the contact's profile image .

  • Use this color to set the background color of the R.id.vPalette view containing contact's name in ContactsActivity and DetailsActivity.

  • The Palette API requires a bitmap of the image you want to extract the colors from as a parameter. You can use Picasso to get a callback with a bitmap, which can then be used to extract the most vibrant color from the Palette.

  • In ContactsAdapter.java and DetailsActivity.java, you'll need to change the way the profile image is being loaded into the ImageView as 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 Palette API.

  1. Test your app
  • If you were able to successfully extract the vibrant color from the profile image using the Palette API to set the background color of your views, you should see the following output:

  1. 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.
  • ContactsActivity and DetailsActivity share three views: ivProfile, vPalette and tvName.
  • Animate these three views while transitioning from ContactsActivity to DetailsActivity and vice versa.
  • Refer to the Shared Element Activity Transition cliffnotes for guidelines on implementing hero transitions.
  1. Test your app
  • Your activity transition should look like following:

  1. Add Floating Action Button
  • Add a floating action button to DetailsActivity to 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.gradle file.

  • Next, add the custom FloatingActionButton view to your activity_details.xml layout 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.java file 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.

  1. 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);
            }
        });
    
        // ...
    }
  1. Test your app
  • Your app, with a floating action button should look like this:

  1. Enable Up Button on ActionBar
  • The navigation button or the up button appears in the ActionBar alongside 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);
    
          // ...
    }
  1. 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() and exitReveal() transitions on the floating action button.

  • Make sure to enable exit reveal transition on press of ActionBar up button or back button, call exitReveal() from onOptionsItemSelected() and onBackPressed() as mentioned in the guide.

  1. Test your app
  • Heres the final app with all the material widgets and animations you implemented during this exercise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment