Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

L-release-like Touch Ripple animation on pre-L

I love the new Touch Ripple animation that was introduced in the new Android L-release as part of the new UI philosophy Material Design.

You can find a video of it in the official design spec under surface reaction here: http://www.google.com/design/spec/animation/responsive-interaction.html

It's basically a dark-gray circle that fades in at the center of the view and grows as it fades out again, eventually filling the whole view with a light gray before disappearing again.

I'd like to add the very same animation to a view in my app that is targetting ICS.

I am a bit clueless on how to add this animation in my application. The official docs at http://developer.android.com/training/animation/index.html don't seem to cover animations that happen "inside a view". Also, I'd like not to use pre-drawn frame animations (one png resource per frame) if possible.

How would I go about implementing that? Any help is highly appreciated!

like image 333
FD_ Avatar asked Jun 25 '14 20:06

FD_


1 Answers

Something I cooked up quickly, far from ideal, but hey, it's something: Gist

Basically drawing a circle based on an animated radius. To get the exact L-effect, some more tweaking should be done. The interesting code:

@Override
public boolean onTouchEvent(@NonNull final MotionEvent event) {
    if (event.getActionMasked() == MotionEvent.ACTION_UP) {
        mDownX = event.getX();
        mDownY = event.getY();

        ObjectAnimator animator = ObjectAnimator.ofFloat(this, "radius", 0, getWidth() * 3.0f);
        animator.setInterpolator(new AccelerateInterpolator());
        animator.setDuration(400);
        animator.start();
    }
    return super.onTouchEvent(event);
}

public void setRadius(final float radius) {
    mRadius = radius;
    if (mRadius > 0) {
        RadialGradient radialGradient = new RadialGradient(
                mDownX,
                mDownY,
                mRadius * 3,
                Color.TRANSPARENT,
                Color.BLACK,
                Shader.TileMode.MIRROR
        );
        mPaint.setShader(radialGradient);
    }
    invalidate();
}

private Path mPath = new Path();
private Path mPath2 = new Path();

@Override
protected void onDraw(@NonNull final Canvas canvas) {
    super.onDraw(canvas);

    mPath2.reset();
    mPath2.addCircle(mDownX, mDownY, mRadius, Path.Direction.CW);

    canvas.clipPath(mPath2);

    mPath.reset();
    mPath.addCircle(mDownX, mDownY, mRadius / 3, Path.Direction.CW);

    canvas.clipPath(mPath, Region.Op.DIFFERENCE);

    canvas.drawCircle(mDownX, mDownY, mRadius, mPaint);
}

In their talk "What's new in Android", they talked about that this animation actually happens on a separate "Render thread", which will make its debut in the L-release. This will allow smoother animations, even when the UI thread is busy inflating, or doing anything else expensive.

like image 92
nhaarman Avatar answered Oct 16 '22 22:10

nhaarman