如果我们想自定义图形的话,就要使用Canvas,因为Canvas是自定义图形的核心可组合项。在Canvas中,可用空间大小可用通过modifier来设置,例如设置Canvas的可用空间大小为填充其父元素:
Canvas(modifier = Modifier.fillMaxSize()) {
}
Canvas自动提供了一个维护自身状态且限定了作用域的绘图环境--DrawScope,其提供了一些有用的字段:
- drawContext:包含创建图形环境所需依赖项的当前DrawContext;
- center:图形环境当前边界的中心;
- size:当前维度和最大维度的Size对象;
- layoutDirection:绘制的布局的方向
这方便了我们为一组图形元素设置参数,我们用得到最多的可能就是size,因为其它对象基本都在内部引用比较多。
下面画一些基本的图形:
1.画一条线:
/**
* 画线
*/
@Composable
fun compose_drawLine() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
drawLine(
start = Offset(x = canvasWidth, y = 0f), // 起点
end = Offset(x = 0f, y = canvasHeight), // 终点
color = Color.Red // 颜色
)
}
}
2.画一个圆:
/**
* 画圆
*/
@Composable
fun compose_drawCircle() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
drawCircle(
color = Color.Red, // 颜色
center = Offset(x = canvasWidth / 2, y = canvasHeight / 2), // 圆点
radius = size.minDimension / 2 // 半径
)
}
}
3.画一个椭圆:
/**
* 画椭圆
*/
@Composable
fun compose_drawOval() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
drawOval(
color = Color.Red, // 颜色
// 偏移量
topLeft = Offset(canvasWidth / 4, canvasHeight / 4),
// 大小
size = Size(canvasWidth / 2f, canvasHeight / 2f)
)
}
}
4.画一个矩形:
/**
* 画矩形
*/
@Composable
fun compose_drawRect() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasQuadrantSize = size / 2F
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
// inset更改绘图边界并相应地转换绘图
inset(canvasWidth / 4, canvasHeight / 4) {
drawRect(
color = Color.Red, // 颜色
size = canvasQuadrantSize // 大小
)
}
}
}
5.画圆角矩形:
/**
* 圆角矩形
*/
@Composable
fun compose_drawRoundRect() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasQuadrantSize = size / 2F
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
inset(canvasWidth / 4, canvasHeight / 4) {
drawRoundRect(
color = Color.Red,
size = canvasQuadrantSize,
cornerRadius = CornerRadius(100.0f),
alpha = 0.5f, // 透明度
)
}
}
}
6.画一条弧:
/**
* 画弧
*/
@Composable
fun compose_drawArc() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
drawArc(
Color.Red,
0f, // 开始度数
180f, // 结束度数
useCenter = false, // 指示圆弧是否闭合边界中心的标志
// 偏移量
topLeft = Offset(canvasWidth / 4, canvasHeight / 4),
// 大小
size = Size(canvasWidth / 2f, canvasWidth / 2f),
// 样式
style = Stroke(width = 100f, miter = 10f, cap = StrokeCap.Round),
)
}
}
7.画路径:
/**
* 画路径
*/
@Composable
fun compose_drawPath() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
val path = Path();
path.lineTo(canvasWidth / 2, canvasHeight / 2f)
path.lineTo(canvasWidth, 0f)
path.moveTo(canvasWidth / 2, canvasHeight / 2f)
path.lineTo(canvasWidth / 2, canvasHeight)
drawPath(
path = path,
color = Color.Red,
style = Stroke()
)
}
}
8.画点:
/**
* 画点
*/
@Composable
fun compose_drawPoint() {
Canvas(modifier = Modifier.fillMaxSize()) {
val pointerList = mutableListOf<Offset>()
pointerList.add(Offset(100f, 100f))
pointerList.add(Offset(200f, 200f))
pointerList.add(Offset(300f, 300f))
pointerList.add(Offset(400f, 400f))
pointerList.add(Offset(500f, 500f))
drawPoints(
points = pointerList,
pointMode = PointMode.Points,
strokeWidth = 20f,
color = Color.Red,
cap = StrokeCap.Square
)
}
}
9.画图形
/**
* 画图象
*/
@Composable
fun compose_drawImage() {
val imgBitmap = ImageBitmap.Companion.imageResource(R.drawable.flower)
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
drawImage(
image = imgBitmap, // 图片资源
topLeft = Offset(canvasWidth/2, canvasHeight/2), // 偏移量
alpha = 0.5f, // 透明度
)
}
}
备注:如果想画空心圆或空心矩形等,把style设置为Stroke()即可,例如:
/**
* 画圆
*/
@Composable
fun compose_drawCircle() {
Canvas(modifier = Modifier.fillMaxSize()) {
val canvasWidth = size.width // 画布的宽
val canvasHeight = size.height // 画布的高
drawCircle(
color = Color.Red, // 颜色
center = Offset(x = canvasWidth / 2, y = canvasHeight / 2), // 圆点
radius = size.minDimension / 4, // 半径
style = Stroke(3.0f) // 样式
)
}
}