This is a short question:
Suppose I have a View
with the RippleDrawable
as background.
Is there an easy way to trigger the ripple from a specific position without triggering any touch or click events?
This is a short question:
Suppose I have a View
with the RippleDrawable
as background.
Is there an easy way to trigger the ripple from a specific position without triggering any touch or click events?
I used the following Kotlin variant of Luke's code to manually show and hide a ripple when swiping cells out of a RecyclerView:
Yes there is! In order to trigger a ripple programatically you have to set the state of the
RippleDrawable
withsetState()
. CallingsetVisible()
does NOT work!The Solution
To show the ripple you have to set the state to pressed and enabled at the same time:
The ripple will be shown as long as those states are set. When you want to hide the ripple again set the state to an empty
int[]
:You can set the point from which the ripple emanates by calling
setHotspot()
.How it works
I have debugged a lot and studied the source code of
RippleDrawable
up and down until I realised that the ripple is actually triggered inonStateChange()
. CallingsetVisible()
has no effect and never causes any ripple to actually appear.The relevant part of the source code of
RippleDrawable
is this:As you can see if both the enabled and pressed attribute are set then both the ripple and background will be activated and the ripple will be displayed. Additionally as long as you set the focused state the background will be activated as well. With this you can trigger the ripple and have the background change color independently.
If you are interested you can view the entire source code of
RippleDrawable
here.First, you need to get the drawable from the View.
Method
setHotspot(x,y);
is used to set from where the ripple animation will start, otherwise if not set, theRippleDrawable
will take theRect
where it resides (i.e theRect
of the View where it is set as background) and will start the ripple effect from the center.setVisible(true, true)
will make the drawable visible and last argument will force animation regardless of the current drawable state.I incorporated/combined the answers from @Xaver Kapeller and @Nikola Despotoski above:
To programmatically force a ripple effect on command, simply call forceRippleAnimation(), passing the View you want to ripple as a parameter.
Here is combination of Nikola's setHotSpot() and https://stackoverflow.com/a/25415471/1474113