Paint几个枚举/常量值以及ShadowLayer阴影效果
Paint API 之—— 枚举/常量值 及 ShadowLayer 阴影效果
在 Android 的 Paint
类中,枚举和常量值用于控制绘制行为和样式,涵盖了填充模式、线条样式、文本对齐方式等多个方面。ShadowLayer
则是一种特殊的阴影效果,用于为绘制内容(如形状或文本)添加投影,提升视觉层次感。以下将详细介绍 Paint
的主要枚举/常量值以及 ShadowLayer
的使用方法。
Paint 的主要枚举/常量值
Paint
类定义了多个枚举和常量,用于配置绘制样式、行为和效果。以下是常见枚举和常量的概述:
1. Paint.Style(绘制样式)
Paint.Style
枚举定义了绘制内容的填充方式,影响形状或路径的呈现方式。
- 值:
Paint.Style.FILL
:填充整个形状(内部填充)。Paint.Style.STROKE
:仅绘制形状的边框(描边)。Paint.Style.FILL_AND_STROKE
:同时填充内部和描边。- 用途:控制绘制是填充、描边还是两者兼有。例如,绘制实心矩形用
FILL
,绘制空心圆用STROKE
。 - 代码示例:
paint.setStyle(Paint.Style.FILL); // 填充矩形
canvas.drawRect(50, 50, 150, 100, paint);
2. Paint.Cap(线条端点样式)
Paint.Cap
枚举定义了线条或路径端点的形状,适用于 STROKE
模式。
- 值:
Paint.Cap.BUTT
:平直端点(默认,无额外延伸)。Paint.Cap.ROUND
:圆形端点(端点为半圆)。Paint.Cap.SQUARE
:方形端点(端点延伸半个笔触宽度)。- 用途:常用于线条或路径的起点/终点美化,如绘制圆头线条。
- 代码示例:
paint.setStrokeWidth(10f);
paint.setStrokeCap(Paint.Cap.ROUND); // 圆形端点
canvas.drawLine(50, 50, 150, 50, paint);
3. Paint.Join(线条连接样式)
Paint.Join
枚举定义了路径拐角处的连接样式,适用于 STROKE
模式。
- 值:
Paint.Join.MITER
:尖角连接(默认,尖锐拐角)。Paint.Join.ROUND
:圆角连接(拐角为圆弧)。Paint.Join.BEVEL
:斜面连接(平滑切角)。- 用途:用于多段路径(如折线或多边形)拐角的样式调整。
- 代码示例:
paint.setStrokeWidth(10f);
paint.setStrokeJoin(Paint.Join.ROUND); // 圆角连接
Path path = new Path();
path.moveTo(50, 50);
path.lineTo(100, 100);
path.lineTo(50, 150);
canvas.drawPath(path, paint);
4. Paint.Align(文本对齐方式)
Paint.Align
枚举定义了文本绘制时的对齐方式。
- 值:
Paint.Align.LEFT
:文本左对齐(默认)。Paint.Align.CENTER
:文本中心对齐。Paint.Align.RIGHT
:文本右对齐。- 用途:控制文本相对于绘制起点的水平对齐,常用于
Canvas.drawText
。 - 代码示例:
paint.setTextSize(40f);
paint.setTextAlign(Paint.Align.CENTER); // 居中对齐
canvas.drawText("Hello", 100, 100, paint);
5. Paint.FontMetrics(字体度量常量)
Paint.FontMetrics
提供了文本绘制时的垂直度量值,用于精确布局。
- 主要字段:
top
:文本最顶部的相对位置(负值)。ascent
:基线到文本上边缘的距离(负值)。descent
:基线到文本下边缘的距离(正值)。bottom
:文本最底部的相对位置(正值)。leading
:行间距(通常为 0 或小值)。- 用途:计算文本高度、行间距或对齐位置。
- 代码示例:
Paint.FontMetrics metrics = paint.getFontMetrics();
float textHeight = metrics.descent - metrics.ascent;
6. 其他常量(部分常见标志)
Paint.ANTI_ALIAS_FLAG
:开启抗锯齿,平滑边缘(默认推荐开启)。Paint.DITHER_FLAG
:开启抖动,优化颜色过渡(适用于低色深设备)。Paint.FILTER_BITMAP_FLAG
:开启位图过滤,提升缩放质量。- 代码示例:
paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
ShadowLayer 阴影效果
ShadowLayer
是一种特殊的 Paint
效果,通过 Paint.setShadowLayer(float radius, float dx, float dy, int color)
方法为绘制内容(形状、文本等)添加阴影效果。阴影本质是一个模糊的颜色投影,增强立体感。
参数说明
radius
:模糊半径(float),值越大阴影越模糊。设为 0 则禁用阴影。dx
:阴影在 X 轴的偏移量(float),正值向右,负值向左。dy
:阴影在 Y 轴的偏移量(float),正值向下,负值向上。color
:阴影颜色(int),通常为半透明颜色(如Color.argb(128, 0, 0, 0)
)。
使用场景
- 为文本添加投影(如标题或标签)。
- 为形状(如按钮、卡片)增加立体感。
- 模拟光源效果(结合动画调整 dx/dy)。
注意事项
- 限制:
ShadowLayer
不支持硬件加速(API 14+ 默认启用硬件加速),需禁用硬件加速或使用软件渲染(View.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
)。 - 性能:大半径阴影或复杂路径可能影响性能,建议谨慎使用。
- 兼容性:API 1+ 支持,但硬件加速限制需注意。
- 清除阴影:调用
paint.clearShadowLayer()
移除阴影效果。
代码示例
以下是一个自定义 View 示例,展示 ShadowLayer
结合不同 Paint
样式和枚举的效果:
import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.View;
public class ShadowLayerView extends View {
private Paint paint;
public ShadowLayerView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 禁用硬件加速以支持 ShadowLayer
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 1. 带阴影的填充矩形
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
paint.setShadowLayer(10f, 5f, 5f, Color.argb(128, 0, 0, 0)); // 半径10,偏移(5,5),半透明黑
canvas.drawRect(50, 50, 150, 100, paint);
// 2. 带阴影的描边圆形(圆形端点)
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10f);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setColor(Color.RED);
paint.setShadowLayer(8f, 3f, 3f, Color.argb(128, 0, 0, 0));
canvas.translate(0, 150);
canvas.drawCircle(100, 50, 50, paint);
// 3. 带阴影的文本(居中对齐)
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(40f);
paint.setTextAlign(Paint.Align.CENTER);
paint.setColor(Color.BLACK);
paint.setShadowLayer(5f, 2f, 2f, Color.argb(128, 255, 0, 0)); // 红色阴影
canvas.translate(0, 150);
canvas.drawText("Shadow Text", 100, 50, paint);
// 4. 清除阴影并绘制路径(圆角连接)
paint.clearShadowLayer();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setColor(Color.GREEN);
Path path = new Path();
path.moveTo(50, 50);
path.lineTo(100, 100);
path.lineTo(50, 150);
canvas.translate(0, 150);
canvas.drawPath(path, paint);
}
}
- 运行效果:从上到下依次显示带阴影的填充矩形、描边圆形、带红色阴影的文本,以及无阴影的折线路径(圆角连接)。
- 动画扩展:通过动态调整
dx
和dy
(配合ValueAnimator
),可以实现阴影移动效果,模拟光源变化。
扩展:Jetpack Compose 中的等效实现
在 Jetpack Compose 中,ShadowLayer
的效果可以通过 Modifier.shadow
或 drawWithCache
结合 Blur
实现。例如:
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.unit.dp
@Composable
fun ShadowExample() {
Canvas(
modifier = Modifier
.size(200.dp)
.shadow(elevation = 10.dp, shape = RectangleShape) // 添加阴影
) {
drawRect(
color = Color.Blue,
topLeft = Offset(50f, 50f),
size = Size(100f, 50f),
style = Fill
)
}
}
- 说明:
Modifier.shadow
提供类似ShadowLayer
的效果,支持圆角和偏移调整。复杂阴影(如文本或路径的自定义阴影)需使用drawWithContent
和Blur
。
注意事项
- 枚举选择:合理选择
Style
、Cap
和Join
能显著提升绘图美观度。例如,ROUND
端点和连接适合平滑曲线,MITER
适合锐利边角。 - ShadowLayer 性能:禁用硬件加速可能导致性能下降,建议在小范围使用或缓存为
Bitmap
。 - 与 Shader/PathEffect 的结合:
ShadowLayer
可与Shader
(渐变填充)或PathEffect
(虚线)组合,创造丰富效果,如带阴影的渐变虚线。 - 调试:Android SDK 的 ApiDemos 包含
Paint
相关示例,可参考学习。
如果需要更详细的某枚举用法(如 FontMetrics
的精确布局)、ShadowLayer
的动画实现,或 Compose 中的高级阴影效果,请告诉我!