If you followed my previous blog post and the linked tutorials, you should have an app that uses the Material Support Library and looks pretty decent. The focus of this post is to help you put some polish on your design, and move closer to the Google Material design guidelines. The best part: none of these tips will require a designer or new assets.
Ripple All the Things
Everyone likes a satisfying ripple effect on buttons, and for everything else to have touch feedback. I’ll show you how to add this effect everywhere you can. Note that the ripples will only show up on devices running Lollipop, and will fall back to a static highlight on previous versions.
Buttons
Most buttons are made with several drawables. Usually you’ll have a pressed and normal version of assets like this:
/drawable/button.xml:https://gist.github.com/johnybot/aa0f43994f240c566e48.js
To get your ripple on, overwrite your button in drawable-v21 and add a ripple effect to your normal button. Using ?android:colorControlHighlight
will give the ripple the same colour as the built-in ripples in your app:
/drawable-v21/button.xml:https://gist.github.com/johnybot/b8557e2532bfdffba941.js
If you don’t like the default grey, you can specify what colour you want colorControlHighlight
to be in your theme. However, I would caution against this, as it distracts from the content of your app and none of the Google-designed apps seem to do it.
Clickable Views
What do you do if you have a View that you want to add a ripple to? A common case is having a LinearLayout with a few items that are clickable. You could create your own drawable with a <ripple>
element, but there is an easier way. Just set the background to ?attr/selectableItemBackground.
In XML:https://gist.github.com/johnybot/14bc0828638e61f83bc5.js
In code:https://gist.github.com/johnybot/99b8aa00a0e725b2185c.js
If you want the ripple to extend past the boundary of the view, then you can instead use ?attr/selectableItemBackgroundBorderless
. This works well with ImageButtons and smaller Buttons that are part of a larger View:
Dialogs with Style
AlertDialogs and ProgressDialogs should automatically show with a material design when running on a Lollipop device. Unfortunately, unless you manually change them, they’ll appear in the default teal. If you’re into the teal, you can leave it as is — but we can easily make the dialogs match our application’s theme.
All Dialogs
Having your buttons fit into your theme is as simple as creating a style and adding it to your theme. The colour of the buttons in an AlertDialog and ProgressBar in a ProgressDialog are decided by the colorAccent attribute.
styles.xml:https://gist.github.com/johnybot/da8ef074fda559afa8cf.js
themes.xml:https://gist.github.com/johnybot/31b9d73ba3017956609f.js
Destructive Dialogs
When the Material Design Guidelines were first released, they included a separate design for destructive dialogs. This design had a red button to emphasize the destructive nature of the action being performed. To implement it, you can overwrite the buttonBarPositiveButtonStyle property in your dialog Theme:
styles.xml:https://gist.github.com/johnybot/089a762b9c8ea7a5e7c2.js
Using this style for a specific AlertDialog requires you to specify a theme in the AlertDialog.Builder constructor:
https://gist.github.com/johnybot/0cd021d01934ce19d4f3.js
Material Dialogs on Every Platform
If you want your Dialogs to have a Material look and feel across all Android versions, you’ll need either custom dialog styles or a library. I am not a fan of reinventing the wheel, so I would suggest using one of the many libraries available:
- https://github.com/afollestad/material-dialogs
- https://github.com/fengdai/AlertDialogPro/
- https://github.com/drakeet/MaterialDialog
Navigation Drawers
Looking at the Material design section on Navigation Drawers will give you a good guideline for designing your DrawerLayout. It provides detailed drawings of padding, text size and colour needed to get a basic Material styled drawer.
Text Color
The guidelines say you should use either your primary colour or black for the selected drawer item. You could detect which item is selected in code and change the textColor, but there is an easier way. By using a ColorStateList, you can specify what colour the text will be when it is selected and unselected.
color/menu_text.xml:https://gist.github.com/johnybot/40d6878bccbeda0d9cd2.js
and in your layout file:https://gist.github.com/johnybot/11320fc445c9af1edcd1.js
Icon Color
You should also change the colour of your menu icons to match the text. If you are on v-21 and up, you can simply set the “android:tint” attribute to the same ColorStateList as before. However, as you’re using the Material Support Library, you’ll need a broader solution to this problem.
One solution would be to have two assets with each image: one for selected and one for unselected. This is a fine solution, but requires both changing assets if you want a colour change, and some experience with image editing software. A way to programmatically colour your icons is with a ColorFilter:
https://gist.github.com/johnybot/38894e2232d6fee054cd.js
This Stack Overflow post shows you a great way to make your icon change based on its state by creating a subclass of ImageView. You can also reuse your ColorStateList like with the v-21 tint:
https://gist.github.com/johnybot/61bf48309d7e288691bc.js
Shoutouts
@Mike_Worth, @bryanstern, and @stinkley for their continuing insight, @kimli for being the best, and @chrisbanes for his excellent work on the appcompat library.
Conclusion
Getting your app to follow the basics of Google’s Material Design Guidelines is not terribly hard. Many things don’t even require a designer. With these basics in place, you can move on to the more complicated concepts like animation and elevation.
Check out Hootsuite’s new Android redesign, now available in the Play Store.
About the Author
Johnathan Harms is an Android Engineer on the Hootsuite Mobile team, and rapidly rising blog superstar. In his spare time, he likes playing video games and thanking Nick. Follow him on Twitter @johnathanharms.
The drawable folder name should be drawable-v21…. It’s took me hours to figure it out…
LikeLike
hieund You’re absolutely correct! I’ll update the post.
LikeLike
Hi,
Do you know how to change the color of the ripple effect on Clickable Views? I would like to have the same coloured effect than the button example.
Thanks
LikeLike
Great blog post JohnathanHarms just what I was after.
I understand the button, But with regard to the view example when you all you need to do is add…
android:background=”?attr/selectableItemBackground”
What if also wanted the views background color to be green?
LikeLike
aidanmack1 JohnathanHarms
With a little digging, you can find that you can override the theming of the Theme.Material.Light or the Theme.AppCompat.Light to provide a custom
item name=”selectableItemBackground” @drawable/itembackgroundmaterial /item
The default material itembackgroundmaterial can a ripple and so you can define your own ripple drawable and give it a color of green if you’d like.
LikeLike
simtse aidanmack1 JohnathanHarms Thanks Simtse, but wouldnt that effect all ripples? I/we need it specific to a view.
Im thinking If I have a view thats green one thats blue, one thats got a photo in ect.
Ive noticed the likes of bbc news, gmail all use the ripple effect on large complex layouts.
LikeLike
aidanmack1 simtse JohnathanHarms
If you didn’t want it system wide, you can just change the background with a custom ripple drawable that looks very similar to itembackgroundmaterial. I thought you wanted it throughout. But if you wanted it just for that screen then use a custom drawable.
In the article by @JonathanHarms, the suggestion would make sure you use a consistent ripple effect throughout the app. So in your case, you want something more specific. Does that help?
LikeLike
Needless to say, but… Excellent thread!
LikeLike
I cant actually get android:background=”?attr/selectableItemBackground” to work. I have it on linearlayout. Do I have to change my theme or make the linearlayout clickable or something?
Thanks
Aidan
LikeLike
Add a android:clickable=”true” tag to your view.
LikeLike
adrianvovk Thanks alot
I only made this account to thank you for pointing out this critical attribute
LikeLike
Very nice tutorial. keep sharing <a href=”http://blog.nkdroidsolutions.com/android-ripple-effect-example-code/” target=”_blank” rel=”dofollow”></a>
LikeLike
Hi https://twitter.com/JohnathanHarms
I have started learning android development, so maybe my question is very basic, Please reply if you have time.
Question:
1. If I follow the steps of getting ripple effect for button, then all the buttons in my app get ripple effect. Is there anyway I get ripple effect for some button only?
(I do understand to have consistence look-N-feel throughout app but I require this)
Is it possible to get ripple effect on older device prior to Android L, at-least kitkatt using some sort of support library?
Thanks a lots for this helpful post.
LikeLike
Hi https://twitter.com/JohnathanHarms
I have started learning android development, so maybe my question is very basic, Please reply if you have time.
Question:
1. If I follow the steps of getting ripple effect for button, then all the buttons in my app get ripple effect. Is there anyway I get ripple effect for some button only?
(I do understand to have consistence look-N-feel throughout app but I require this)
Is it possible to get ripple effect on older device prior to Android L, at-least kitkatt using some sort of support library?
Thanks a lots for this helpful post.
LikeLike
android:alertDialogTheme or alertDialogTheme (without namespace)?
LikeLike