如何在Canvas上绘制类似Google图表的路径阴影(自定义视图场景)
实现Canvas贴合路径的阴影效果(类似Google图表样式)
核心思路
这种贴合路径的阴影不能用Canvas默认的setShadowLayer()(默认阴影是给整体绘制对象加的,无法适配不规则路径),核心是复制图表路径并做模糊处理,把模糊后的路径放在原路径下方当阴影,最后用原路径覆盖。
步骤1:准备图表路径
先创建好你要绘制的图表路径(比如折线填充后的闭合面积路径、折线线条路径),假设已有Path chartPath对象,包含完整的图表轮廓(比如折线+底部横轴围成的闭合区域)。
步骤2:创建模糊滤镜
用Android的BlurMaskFilter生成模糊效果,这是实现贴合阴影的关键:
// 把dp转成像素,模糊半径可根据视觉需求调整 float blurRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()); BlurMaskFilter blurFilter = new BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.NORMAL);
Blur.NORMAL是内外都模糊,适合阴影效果;仅需外模糊可改用Blur.OUTER。
步骤3:绘制模糊阴影路径
在绘制原图表前,先画模糊后的路径当阴影:
Paint shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG); shadowPaint.setColor(Color.parseColor("#33000000")); // 半透明黑色,可按需调整阴影颜色 shadowPaint.setMaskFilter(blurFilter); canvas.drawPath(chartPath, shadowPaint);
如果是折线线条阴影,路径就是折线本身;如果是面积图,路径必须是闭合状态,这样阴影会贴合整个填充区域。
步骤4:绘制原图表路径
在阴影上方绘制原图表路径,用正常画笔覆盖阴影:
Paint chartPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chartPaint.setColor(Color.parseColor("#4285F4")); // 图表主色,比如Google蓝 chartPaint.setStyle(Paint.Style.FILL); // 面积图用FILL,折线图改用STROKE canvas.drawPath(chartPath, chartPaint);
额外优化点
- 阴影偏移:想要阴影向下/向右偏移,可在绘制阴影前平移Canvas,完成后恢复:
canvas.save(); canvas.translate(2, 2); // 向右向下各偏移2像素 canvas.drawPath(chartPath, shadowPaint); canvas.restore(); - 性能优化:
BlurMaskFilter在API<18的系统上可能有性能损耗,复杂场景可改用RenderScript做模糊;普通图表路径用BlurMaskFilter足够。 - 适配折线场景:如果是纯折线(非填充),确保路径是连续线条,画笔设置
STROKE样式,阴影会自动贴合线条轮廓。
内容的提问来源于stack exchange,提问作者Sharad
相关产品推荐
相关产品推荐

