Compose_20--画布(Canvas)_放弃了放弃的博客-程序员秘密

技术标签: android  Android-compose  

如果我们想自定义图形的话,就要使用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)  // 样式
        )
    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42404361/article/details/122246259

智能推荐

获取磁盘id与序列号_获取硬盘id_道道道人间道的博客-程序员秘密

磁盘序列号获取:1.网上普遍流传的diskpart命令获取的磁盘id并不是磁盘唯一序列号2.获取磁盘唯一序列号,使用wmic命令:wmic diskdrive get serialnumber关于该命令其他用法可百度转载自:window磁盘id与序列号_xsqm123的博客-程序员秘密_磁盘id与硬盘序列号...

Android开发UI之全屏沉浸式应用_犬小哈的博客-程序员秘密

Android开发UI之全屏沉浸式应用前言1.确定一种方式2.使用非粘性沉浸模式3.使用粘性沉浸模式Adnroid 4.4中引入为setSystemUiVisibility()引入了一个新标签SYSTEM_UI_FLAG_IMMERSIVE,它可以让应用进入真正的全屏模式。当这个标签与SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCRE

java将对象数组作为Map的key值,对数据进行增删改查_PMr.小杰的博客-程序员秘密

java将对象数组作为Map的key值,对数据进行增删改查源文件Student.javaimport java.util.Map;import java.util.Scanner;public class Student implements Comparable&lt;Student&gt;{ int id; String name; String sex; int age;...

Json与Java对象的相互转换_json数据转换为java对象_成神之路.java的博客-程序员秘密

一、json二、json与Java的相互转换1.JSON解析器:常见的解析器:Jsonlib,Gson,Fastjson,Jackson2.JSON转为Java对象的使用步骤(以使用Jackson工具为例): 1)导入jackson的相关jar包2)创建Jackson核心对象 ObjectMapper3)调用ObjectMapper的方法进行转换Jackson完成数据转换使用的类是ObjectMapper,它有两个主要方法:...

python编写库存管理_python编写商品管理_光影帽子的博客-程序员秘密

# 1、实现一个商品管理的程序。# #输出1,添加商品 2、删除商品 3、查看商品# 添加商品:# 商品的名称:xxx 商品如果已经存在的话,提示商品商品已经存在# 商品的价格:xxxx 数量只能为大于0的整数# 商品的数量:xxx,数量只能为大于0的整数# 2、删除商...

Shell中遍历整个目录查找某个关键字_杰瑞26的博客-程序员秘密

经常会拍碰到需要遍历整个目录中的文件,查找是否包含某个关键字的情况。 比如说,我需要在/etc目录下查找是否有/bin/bash关键字,来确定是通用的Bash还是CSH,KSH等,这个时候,就要用到find和grep关键字,通用的做法:方法一: 通过find结合xargs来查找# find /etc -type f | xargs grep "/bin/bash"备注: 1.

随便推点

Linux文件属性与文件权限_在linux系统中按照对文件的拥有权把用户分为三种拥有者所属组和其他人这种说法对吗_MultiSkill的博客-程序员秘密

我们在Linux中经常看到文件属性中包含类似于“-rwxr--r--”的字符串,这些有什么含义?文件的属性又包含什么内容?如何修改文件属性呢?

[OS]秋招-计算机基础-操作系统_Hosea14的博客-程序员秘密

进程间通信方式?管道(无名管道、有名管道--FIFO)消息队列(posix--mq_xxx、system--msgxxx)信号量文件记录与上锁共享内存(posix--shm_xxx、system--shmxxx)unix域socket信号(kill函数作为进程间发送信号,kill命令就是很好的例子)线程通信事件临界区互斥量信号量读写锁条件变量自旋锁屏障操作系

FPGA设计-时序约束(上篇,理论篇)_fpga时序约束_禾刀围玉的博客-程序员秘密

最近都在做ARM的方面学习工作,感觉有必要记录下来之前FPGA的工作,好记性也不如烂笔头;说起FPGA,断断续续的也用过4,5年了,中间接触过DSP,就是因为没有记录文档资料,目前几乎快忘光了;FPGA方面的心得,将会由以下几个方面进行总结:1.FPGA时序约束以及高速ADC约束实例2.TDC进位延时链设计以及研究3.TDC的精度以及自动校正算法的实现STA:S

Candence Orcad 无法启动出现Capture.exe找不到cdn_sfl401as.dll问题_candence安装缺少capture_emouse的博客-程序员秘密

一直用的好好的Orcad突然启动出现Capture.exe找不到cdn_sfl401as.dll问题,一开始琢磨着小红伞老是把我的破解文件当病毒杀,是不是给杀掉了,于是关闭小红伞重新破解还是不行,琢磨着估计要重新安装了,但是实在不想重新安装,于是百度了一下,看到有人说是系统环境变量的问题,于是就试试看,缺少环境变量肯定就找不到对应文件了,经过测试需要添加以下两个环境变量:第一个%C

linux内核sysfs详解-1,linux内核文件系统:proc、tmpfs、devfs、sysfs简要介绍_weixin_39835321的博客-程序员秘密

linux内核文件系统:proc、tmpfs、devfs、sysfsproc:虚拟文件系统,在linux系统中被挂载与/proc目录下。里面的文件包含了很多系统信息,比如cpu负载、 内存、网络配置和文件系统等等。我们可以通过内部文本流来查看进程信息(正在运行的各个进程的PID号也以目录名形式存在/proc目录下)和机器的状态。常见的目录:apm # 高级电源管理信息bus...

angularjs 单选按钮 默认选中_楚码小生的博客-程序员秘密

如图:代码如下: 特殊日期:&lt;label&gt; &lt;input type="radio" ng-value=true ng-model="state" name="selectState"&gt;是&lt;/label&gt;&lt;label&gt; &lt;input type="radio" ng-value=false ng-model=...

推荐文章

热门文章

相关标签