我快速制作了一些东西,离理想还很远,但是嘿,这总比没有好: Gist
基本上是根据动态半径绘制圆形。要获得精确的L效果,需要进行一些微调。有趣的代码如下:
@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);
}
在他们的演讲"Android的新特性"中,他们提到这个动画实际上发生在一个单独的"渲染线程"上,在L版本中首次亮相。这将允许更平滑的动画,即使UI线程正在忙于膨胀或执行其他昂贵的操作。