Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play ripple animation without user interaction

I know that I can set android:background="?android:attr/selectableItemBackground" to any View to get the nice ripple effect from Android Lollipop.This works well for views which are touched by the user. But what if I want to play the ripple animation without user interaction?

In my application I want to draw attention to a view by playing a ripple animation on this view. How can I do this? I do not found a way to get an Animatior object for the ripple animation. So how can I set a ripple animation to a view from code without user interaction?

like image 742
Cilenco Avatar asked Aug 17 '16 12:08

Cilenco


1 Answers

Unfortunately no accessible method is available to play ripple animation. But I could think of two possible ways to achieve this

#1 Using reflection

public static void simulateButtonPress(final View view)
{
    Drawable drawable = view.getBackground();
    if( drawable instanceof RippleDrawable )
    {
        try
        {
            final RippleDrawable rd = ((RippleDrawable)drawable);
            final Method setRippleActive = rd.getClass().getDeclaredMethod("setRippleActive", boolean.class);
            setRippleActive.setAccessible(true);
            setRippleActive.invoke(rd, true);  //setRippleActive(true)

            //exit ripple effect after 250 milliseconds
            new Handler().postDelayed(new Runnable()
            {
                @Override
                public void run()
                {
                    try
                    {
                        setRippleActive.invoke(rd, false); //setRippleActive(false)
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }, 250);

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

#2 By simulating Motion Events ACTION_DOWN and ACTION_CANCEL

public static void simulateButtonPress(final View view)
{
    final long now = SystemClock.uptimeMillis();
    final MotionEvent pressEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, view.getWidth()/2, view.getHeight()/2, 0);
    view.dispatchTouchEvent(pressEvent);

    new Handler().postDelayed(new Runnable()
    {
        @Override
        public void run()
        {
            final long now = SystemClock.uptimeMillis();
            final MotionEvent cancelEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, view.getWidth()/2, view.getHeight()/2, 0);
            view.dispatchTouchEvent(cancelEvent);
        }
    }, 250);
}
like image 161
Sohaib Avatar answered Nov 13 '22 05:11

Sohaib