在drawCircle(或drawRoundRect)期间实现setShadowLayer效果,而不关闭硬件加速

时间:2014-11-23 18:34:33

标签: android

目前,我有一款支持Android 2.3及以上版本的应用。

在我的自定义视图绘制操作中,我需要在绘制圆圈时放下阴影。

ballPaint.setShadowLayer(shadowSize, shadowSize, shadowSize, historyChartBallShadow);
canvas.drawCircle(px, py, this.ballSize, ballPaint);

我也明白,随着硬件加速开启,我不会有这样的阴影效果

setShadowLayer Android API differences

但是,我意识到一旦通过view.setLayerType(View.LAYER_TYPE_SOFTWARE, null)关闭了硬件加速,我的整个自定义视图绘制操作变得非常慢。

我在想,有没有其他方法可以达到类似的阴影效果。 (A"模糊"黑色圆圈阴影)

enter image description here

不关闭硬件加速?

p / s即使我想使用Android draw with blur中的BlurMaskFilter,我也意识到它也不支持硬件加速。

1 个答案:

答案 0 :(得分:2)

我找到了实现这一目标的方法。首先,我们构建球+阴影离屏图像。注意,通过使用屏幕外位图绘制技术,不会涉及GPU。关键是,不要使用Canvas中的onDraw来执行drawCircle

相反,构建我们自己的Canvas,由屏幕外位图支持。

private Bitmap generateBallBitmap() {
    final int ballShadowSize = Utils.dpToPixel(BALL_SHADOW_SIZE);

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(historyChartBallColor);
    paint.setShadowLayer(ballShadowSize, ballShadowSize, ballShadowSize, historyChartBallShadow);

    Bitmap bitmap = Bitmap.createBitmap((int)((ballSize + ballShadowSize)*2f), (int)((ballSize + ballShadowSize)*2f), Bitmap.Config.ARGB_8888);
    bitmap.eraseColor(Color.TRANSPARENT);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawCircle(ballSize, ballSize, ballSize, paint);

    return bitmap;
}

在自定义视图onDraw功能中,只需直接绘制屏幕外位图。

if (null == this.ballBitmap) {
    this.ballBitmap = generateBallBitmap();
}
canvas.drawBitmap(this.ballBitmap, px - this.ballSize, py, null);

对于整个过程,我只是依赖于图层类型的默认值,而不是明确调用setLayerType

结果很快,但阴影效果也是可见的。