ActionBar / Drawables / Ripple / Ripple Drawable

Ripples – Part 3

Previously in this series we’ve looked at the ripple effect touch feedback which was introduced in the Android-L developer preview, and looked at how we can define ripples, and also integrate them with existing background drawables. In this concluding article we’ll look at styling our ripples.

In the first article in this series I advocated using android:colorControlHighlight to define the colour of the ripple in the XML drawable definition. The reason for this is that in the Android-L developer preview there are some new colour constant values which make giving our apps a consistent colour theme is much easier. Very much easier!.

The more observant may have noticed that the test app containing the sample code is actually themed using Styling Android green on the ActionBar and status bar. However, I did not spend much time and effort in doing this, take a look at the theme:

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
    <item name="android:colorPrimary">@color/sa_green</item>
    <item name="android:colorPrimaryDark">@color/sa_green_dark</item>
    <item name="android:colorAccent">@color/sa_green</item>
  </style>
</resources>

All we do is provide definitions for some specifically named attributes in our theme, and the colour values which we provide get applied by the Android framework. android:colourPrimary defines the ActionBar colour; android:colorPrimaryDark defines the status bar colour; and android:colorAccent defines the accent colour used in the PagerTabStrip of our ViewPager.

While this is really easy, and certainly makes theming ActionBar colours much easier, what’s it got to do with ripples? Well we can use exactly the same technique to theme our ripples and tie the visual feedback to our branding colours. That is the reason behind using android:colorControlHighlight because this attribute is used throughout the theme on many different types of widget to make providing a consistent theme very much easier.

Let’s demonstrate this by adding a single line to our theme:

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
    <item name="android:colorPrimary">@color/sa_green</item>
    <item name="android:colorPrimaryDark">@color/sa_green_dark</item>
    <item name="android:colorAccent">@color/sa_green</item>
    <item name="android:colorControlHighlight">@color/sa_green_transparent</item>
  </style>
</resources>

The colour value that we’ve assigned is basically @color/sa_green but with 50% transparency.

Without any additional code changes, let look at the difference this makes:

So we have completely themed all of our ripple animations by adding a colour definition, and because we utilised the correct colour attribute when we defined our ripple drawable in XML. That is pretty powerful stuff, but it gets better still!

Up to now we’ve used FrameLayout to show ripple animations working over a large area, so that we can see how they’re working. But what if we use a widget which is inherently clickable, such as a Button? Here’s our simple layout containing a Button without any inline theming or styling:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/layout"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  android:paddingBottom="@dimen/activity_vertical_margin"
  tools:context=".RipplesActivity">

  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:padding="32dp"
    android:text="@string/press_me"/>

</FrameLayout>

When we click this we can see that the colour definition from out theme get automatically applied:

So when we’re using standard clickable controls, the framework is doing an awful lot for us provided we get our colour definitions right. However when we’re using custom components it is important to follow the convention (as we did in our XML definitions) as then we can reap the same benefits within our custom controls.

That concludes this overview of Ripples. The source code for this article is available here.

© 2014, Mark Allison. All rights reserved.

Copyright © 2014 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.

8 Comments

  1. What if i want to set a unique color for the entire activity from code. My case is that I’m using the new feature in Android L to generate a color from an image and would like to then assign it to the highlight color of all the items on the view. Any idea?

    1. The answer to your question is actually contained in the articles on Ripples on this site – specifically Ripple bounds are covered in and a mechanism for constraining them is covered in . Perhaps you should try actually reading my articles to see if they answer your question before posting a question.

  2. This is pretty cool… But its not giving haptic (vibration) feedback along with ripple. Can you please help for it? I tried android:hapticFeedbackEnabled=”true” in view but gives only ripple. Any way to implement?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.