Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use RippleDrawable programmatically in code (not xml) with Android 5.0 Lollipop?

I have the following code for my ripple:

<?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android"     android:color="?android:colorControlHighlight">     <item android:id="@+id/rip">          <shape android:shape="oval">             <solid android:color="?android:colorAccent"/>         </shape>     </item> </ripple> 

Now I want to give the user the possibility to choose own colors, so I need to create the ripple programmatically.
I found this and I think this is the right way to do it, but I don't know how to handle with this.

The ripple will be used here:

<ImageButton     android:id="@+id/add_button"     android:layout_width="@dimen/diameter"     android:layout_height="@dimen/diameter"     android:layout_gravity="end|bottom"     android:layout_marginBottom="@dimen/add_button_margin"     android:layout_marginEnd="@dimen/add_button_margin"     android:layout_alignParentBottom="true"     android:layout_alignParentEnd="true"     android:src="@drawable/ic_action_add_person"     android:tint="@android:color/white"     android:background="@drawable/oval_ripple"     android:elevation="@dimen/elevation_low"     android:stateListAnimator="@anim/button_elevation"     android:contentDescription="Neuer Spieler" /> 

I need to set the background to a RippleDrawable like this:

addButton.setBackground(ripple); 
like image 753
ich5003 Avatar asked Jan 05 '15 21:01

ich5003


2 Answers

This is how I was able to achieve this.

Note that this is Api 21+ only so you will have to fallback to a normal Drawable if you support lower versions.

public static RippleDrawable getPressedColorRippleDrawable(int normalColor, int pressedColor) {     return new RippleDrawable(getPressedColorSelector(normalColor, pressedColor), getColorDrawableFromColor(normalColor), null); }  public static ColorStateList getPressedColorSelector(int normalColor, int pressedColor) {     return new ColorStateList(         new int[][]             {                 new int[]{android.R.attr.state_pressed},                 new int[]{android.R.attr.state_focused},                 new int[]{android.R.attr.state_activated},                 new int[]{}             },         new int[]             {                 pressedColor,                 pressedColor,                 pressedColor,                 normalColor             }     ); }  public static ColorDrawable getColorDrawableFromColor(int color) {     return new ColorDrawable(color); } 

Edit: I tinkered with this some more and discovered that the ColorStateList doesn't need to be nearly as complex as the above solution. I have simplified it to the below snippet. (Everything else in the above code block is the same. I only changed the ColorStateList creation.) I will leave the above block as the original, in case this method doesn't work for someone.

new ColorStateList(     new int[][]         {             new int[]{}         },     new int[]         {             pressedColor         } ); 
like image 130
kdenney Avatar answered Sep 17 '22 17:09

kdenney


public static Drawable getAdaptiveRippleDrawable(     int normalColor, int pressedColor) {     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {         return new RippleDrawable(ColorStateList.valueOf(pressedColor),                 null, getRippleMask(normalColor));     } else {         return getStateListDrawable(normalColor, pressedColor);     } }  private static Drawable getRippleMask(int color) {     float[] outerRadii = new float[8];     // 3 is radius of final ripple,      // instead of 3 you can give required final radius     Arrays.fill(outerRadii, 3);      RoundRectShape r = new RoundRectShape(outerRadii, null, null);     ShapeDrawable shapeDrawable = new ShapeDrawable(r);     shapeDrawable.getPaint().setColor(color);     return shapeDrawable; }  public static StateListDrawable getStateListDrawable(     int normalColor, int pressedColor) {     StateListDrawable states = new StateListDrawable();     states.addState(new int[]{android.R.attr.state_pressed},          new ColorDrawable(pressedColor));     states.addState(new int[]{android.R.attr.state_focused},          new ColorDrawable(pressedColor));     states.addState(new int[]{android.R.attr.state_activated},          new ColorDrawable(pressedColor));     states.addState(new int[]{},          new ColorDrawable(normalColor));     return states; } 

You can get the drawable and apply to any view using view.setDrawable.
For Lollipop+ devices you will get ripple else it will change the color of view.

like image 45
Ashok Varma Avatar answered Sep 18 '22 17:09

Ashok Varma