Compose Canvas基础(1) drawxxx()绘制方法

Compose Canvas基础(1) drawxxx方法

  • 前言
  • Canvas是什么
  • drawxxx()绘制方法
    • drawCircle 画圆
      • 不填充颜色
      • 设置线条的宽度
    • drawRect 画矩形
    • drawPoints 画点
      • pointMode
    • drawOval 画椭圆
    • drawLine 画线
    • drawRoundRect 画圆角矩形
    • drawArc 绘制弧形或扇形
      • useCenter
    • drawPath 画自定义图形
  • 完整代码
  • 总结

前言

阅读本文需要一定compose基础,如果没有请移步Jetpack Compose入门详解(实时更新)

本文介绍Compose Canvas基础,介绍Canvas可组合项依赖的原理和绘制相关的内置api。

本文的写作顺序和风格参造HenCoder Android 开发进阶: 自定义 View 1-1 绘制基础

Canvas是什么

Canvas可组合项允许我们在屏幕上指定区域并在此区域上执行画布绘制。必须使用修饰符指定大小,无论是通过modifier.size修饰符指定精确大小,还是通过modifier.fillMaxSize、ColumnScope.weight等指定相对于父项的大小。如果父项包装此子项,则必须仅指定精确大小。
参数:

  • modifier-指定此可组合文件的大小策略的强制修饰符
  • onDraw-将被调用以执行绘图的lambda。请注意,这个lambda将在绘制阶段被调用,您不能访问组合范围,这意味着它内部的可组合函数调用将导致运行时异常
@Composable
fun Canvas(modifier: Modifier, onDraw: DrawScope.() -> Unit) =
    Spacer(modifier.drawBehind(onDraw))

可以看到所有的Canvas可组合项都用Spacer创建了一个空白的可组合项,然后调用了Modifier.drawBehind方法。而drawBehind的作用是将onDraw中的内容绘制到修改内容后面的画布中。

drawxxx()绘制方法

以draw开头的api是Canvas绘图的一种方式
Compose Canvas基础(1) drawxxx()绘制方法_第1张图片
从后面衔接的单词可以看出具体我们能画个什么东西出来,下面我们举个简单例子。

drawCircle 画圆

例子如下:

    Canvas(modifier = Modifier, onDraw = {

		drawCircle(
            color = Color(0xFFF44336),
            radius = size.width / 4,
            center = center
        )

    } )

注意,上例中的size和center表示Canvas 的尺寸和中心

效果
Compose Canvas基础(1) drawxxx()绘制方法_第2张图片

参数解释:

  • color -画圆填充的颜色
  • radius- 圆的半径
  • center 圆的圆心
  • alpha-应用于圆形的不透明度,从0.0f到1.0f,分别表示完全透明到完全不透明
  • style-是否描边或填充圆
  • colorFilter-绘制到目标时应用于颜色的colorFilter
  • blendMode-要应用于笔刷的混合算法

不填充颜色

那么我们只想画一个没有填充颜色,只有描边颜色的圆要怎么做呢?添加style就够了

        drawCircle(
            color = Color(0xFFF44336),
            radius = size.width / 4,
            center = center,
            style = Stroke()
        )

效果:
Compose Canvas基础(1) drawxxx()绘制方法_第3张图片

设置线条的宽度

改变上例代码:

        drawCircle(
            color = Color(0xFFF44336),
            radius = size.width / 4,
            center = center,
            style = Stroke(20f)
        )

效果:
Compose Canvas基础(1) drawxxx()绘制方法_第4张图片

drawRect 画矩形

其实也是差不多的,示例代码如下:

 		drawRect(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
        )

        drawRect(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
            style = Stroke(20f),
            topLeft = Offset(300F, 0F)
        )

效果如下:
Compose Canvas基础(1) drawxxx()绘制方法_第5张图片

参数解释:

  • topLeft 往左边偏移的坐标

drawPoints 画点

示例代码如下:

        val list: MutableList<Offset> = mutableListOf()
        val offset = Offset(100f, 100f)
        val offset1 = Offset(200f, 200f)
        val offset3= Offset(100f, 300f)
        list.add(offset)
        list.add(offset1)
        list.add(offset3)
        drawPoints(
            points = list,
            pointMode = PointMode.Points,
            color = Color.Black,
            strokeWidth = 20f,
            cap = StrokeCap.Round
            )

效果如下:
Compose Canvas基础(1) drawxxx()绘制方法_第6张图片
参数解析:

  • points-使用指定PointMode绘制的点列表
  • pointMode-用于指示如何绘制点的pointMode
  • color-应用于点的颜色
  • alpha-应用于0.0f到1.0f路径的不透明度,分别表示完全透明到完全不透明
  • strokeWidth-要应用于线条的笔划宽度
  • cap-应用于线段末端的处理
  • pathEffect-应用于点的可选效果或模式
  • colorFilter-绘制到目标时应用于颜色的colorFilter
  • blendMode-绘制路径时应用于路径的混合算法

pointMode

我们重点说下pointMode

  1. PointMode.Points 也就是上例代码使用的,会 分别绘制每个点。
    如果Paint.strokeCap为strokeCap.Round,则每个点都绘制为直径为Paint.stronkeWidth的圆,并按照Paint(忽略Paint.style)的说明填充。
    否则,每个点都将绘制为一个轴对齐的正方形,边长为Paint.strokeWidth,按“绘制”(忽略“绘制.样式”)所述填充

  2. PointMode.Lines 将两个点的每个序列绘制为线段。如果点数为奇数,则忽略最后一个点。线条按“绘制”(Paint)所述进行笔划处理(忽略“绘制.样式”)。
    Compose Canvas基础(1) drawxxx()绘制方法_第7张图片
    将pointMode更改为Lines的效果

  3. PointMode.Polygon 将整个点序列绘制为一条线。线条按“绘制”(Paint)所述进行笔划处理(忽略“绘制.样式”)。
    Compose Canvas基础(1) drawxxx()绘制方法_第8张图片
    将pointMode更改为Polygon的效果

drawOval 画椭圆

示例代码:

        drawOval(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
        )

和画矩形的参数是一模一样的

drawLine 画线

示例代码:

        drawLine(
            color = Color.Green,
            start = Offset(100f,100f),
            end = Offset(100f,200f),
            strokeWidth = 20f
        )

效果:
Compose Canvas基础(1) drawxxx()绘制方法_第9张图片
如果你仔细观察可以发现drawPoints的PointMode.Lines模式可以实现drawLine一样的效果,这是没有差别的,全看个人喜好。

drawRoundRect 画圆角矩形

示例代码:

        drawRoundRect(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
            style = Stroke(20f),
            topLeft = Offset(300F, 0F),
            cornerRadius = CornerRadius(50f)
        )

效果:

Compose Canvas基础(1) drawxxx()绘制方法_第10张图片
参数解析:

  • cornerRadius 圆角的度数,如果不传和传负数则为0,就变成画矩形了

drawArc 绘制弧形或扇形

示例代码:

        drawArc(
            color = Color(0xFFF44336),
            size = Size(size.width/2,size.height/4),
            startAngle = 0f,
            sweepAngle = 90f,
            useCenter = true
        )

效果:
Compose Canvas基础(1) drawxxx()绘制方法_第11张图片
参数解析:

  • startAngle 以度为单位的起始角度。0表示3点钟
  • sweepAngle-相对于startAngle顺时针绘制的圆弧的大小(以度为单位)
  • useCenter-指示圆弧是否要闭合边界中心的标志

useCenter

将useCenter = false

        drawArc(
            color = Color(0xFFF44336),
            size = Size(size.width/2,size.height/4),
            startAngle = 0f,
            sweepAngle = 90f,
            useCenter = false
        )

效果如下:
Compose Canvas基础(1) drawxxx()绘制方法_第12张图片

drawPath 画自定义图形

示例代码:

 val path = Path()
        path.moveTo(100f, 100f);
        path.lineTo(200f,200f)
        path.lineTo(100f,200f)
        drawPath(path,color = Color(0xFFF44336) )

效果:
Compose Canvas基础(1) drawxxx()绘制方法_第13张图片
参数解析:

  • Path 要绘制的图形的路径,如果要将两端未连接的线段连接成图形可以使用 path.close()

Path 可以描述直线、二次曲线、三次曲线、圆、椭圆、弧形、矩形、圆角矩形。把这些图形结合起来,就可以描述出很多复杂的图形。下面我就说一下具体的怎么把这些图形描述出来。

Path 有两类方法,一类是直接描述路径的,另一类是辅助的设置或计算。

完整代码



import androidx.compose.foundation.Canvas
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PointMode
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.text.drawText
import androidx.compose.ui.tooling.preview.Preview


/**
 * @author zengyifeng
 * @date createDate:2023-10-03
 * @brief description
 */
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun CanvasView() {

    Canvas(modifier = Modifier, onDraw = {

        drawCircle(
            color = Color(0xFFF44336),
            radius = size.width / 4,
            center = center,
            style = Stroke(20f)
        )


        drawOval(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
        )

        drawRect(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
            style = Stroke(20f),
            topLeft = Offset(300F, 0F)
        )

        val list: MutableList<Offset> = mutableListOf()
        val offset = Offset(100f, 100f)
        val offset1 = Offset(200f, 200f)
        val offset3= Offset(100f, 300f)
        list.add(offset)
        list.add(offset1)
        list.add(offset3)
        drawPoints(
            points = list,
            pointMode = PointMode.Polygon,
            color = Color.Black,
            strokeWidth = 20f,
            cap = StrokeCap.Round
            )


        drawLine(
            color = Color.Green,
            start = Offset(100f,100f),
            end = Offset(100f,200f),
            strokeWidth = 20f
        )


        drawRoundRect(
            color = Color(0xFFF44336),
            size = Size(size.width/4,size.height/4),
            style = Stroke(20f),
            topLeft = Offset(300F, 0F),
            cornerRadius = CornerRadius(50f)
        )


            drawArc(
                color = Color(0xFFF44336),
                size = Size(size.width/2,size.height/4),
                startAngle = 0f,
                sweepAngle = 90f,
                useCenter = false
            )

        val path = Path()
        path.moveTo(100f, 100f);
        path.lineTo(200f,200f)
        path.lineTo(100f,200f)

        drawPath(path,color = Color(0xFFF44336) )



    })
}

总结

本文介绍了Compose Canvas基础,包括Canvas可组合项的使用方法,以及绘制各种形状的api方法。通过本文的介绍,我们可以了解到Canvas绘制的基本原理和常用的api方法,可以为我们后续的Compose开发中提供参考。同时也要注意到不同参数的调整会对绘制结果产生不同的影响。

你可能感兴趣的:(android,jetpack,android)