自定义控件之绘图篇(四)canvas变换与操作

news2024/10/6 2:48:31

在Android中,Canvas类是所有图形绘制的核心,它提供了大量的方法用于绘制各种图形元素以及对这些图形进行变换。自定义控件时,熟练掌握Canvas的变换和操作能力是至关重要的。下面,我们将深入探讨Canvas的变换与操作,包括平移、缩放、旋转、剪切以及路径绘制,同时提供一些实用的代码示例。

平移(translate)

平移是Canvas中最基本的变换之一,它通过translate()方法来实现,可以将坐标原点从左上角移动到指定的位置。这在绘制图形时非常有用,可以让我们更灵活地控制图形在屏幕上的位置。

示例代码:

Java

1canvas.translate(100, 100); // 将坐标原点向右下移动100像素
2paint.setColor(Color.BLUE);
3canvas.drawRect(0, 0, 50, 50, paint); // 在新原点处绘制一个蓝色正方形

缩放(scale)

Canvasscale()方法允许你按比例放大或缩小画布上的内容。这对于实现缩放动画或调整复杂图形的大小特别有用。

示例代码:

Java

1canvas.scale(2, 2); // 将画布内容放大两倍
2paint.setColor(Color.GREEN);
3canvas.drawRect(0, 0, 50, 50, paint); // 绘制一个绿色正方形,实际上是100x100

旋转(rotate)

Canvasrotate()方法可以围绕指定的点旋转画布。这对于实现旋转动画或者需要精确角度定位的图形非常有用。

示例代码:

Java

1canvas.rotate(45, 100, 100); // 以(100, 100)为中心点旋转45度
2paint.setColor(Color.YELLOW);
3canvas.drawRect(0, 0, 50, 50, paint); // 绘制一个黄色正方形,但因旋转而变形

剪切(clip)

CanvasclipRect()方法允许你限制绘图的区域,只在指定的矩形区域内绘制图形。这对于实现复杂的遮罩效果或裁剪图形非常有用。

示例代码:

Java

1canvas.clipRect(50, 50, 150, 150); // 只在50x50至150x150的区域内绘制
2paint.setColor(Color.CYAN);
3canvas.drawRect(0, 0, 200, 200, paint); // 实际上只绘制出100x100的正方形

路径绘制(Path)

Path类提供了丰富的功能来创建复杂的图形路径,如直线、曲线、圆弧等。结合Canvas,可以绘制出极其复杂的图形。

示例代码:

Java

1Path path = new Path();
2path.moveTo(50, 50);
3path.lineTo(100, 100);
4path.lineTo(150, 50);
5path.close(); // 形成一个三角形
6paint.setColor(Color.MAGENTA);
7canvas.drawPath(path, paint);

复合变换

在实际应用中,我们经常需要复合使用多种变换。Canvas提供了save()restore()方法来保存和恢复变换状态,这样可以避免变换的累积效应。

示例代码:

Java

1canvas.save(); // 保存当前状态
2canvas.translate(100, 100);
3canvas.rotate(45); // 先平移再旋转
4paint.setColor(Color.RED);
5canvas.drawRect(0, 0, 50, 50, paint);
6canvas.restore(); // 恢复到保存的状态

完整的自定义控件示例

现在,让我们创建一个简单的自定义控件,展示如何在一个View中使用上述的Canvas变换和操作。

Java
1public class TransformView extends View {
2    private Paint mPaint;
3
4    public TransformView(Context context) {
5        super(context);
6        init();
7    }
8
9    public TransformView(Context context, @Nullable AttributeSet attrs) {
10        super(context, attrs);
11        init();
12    }
13
14    private void init() {
15        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
16    }
17
18    @Override
19    protected void onDraw(Canvas canvas) {
20        super.onDraw(canvas);
21        
22        // 平移
23        canvas.save();
24        canvas.translate(100, 100);
25        mPaint.setColor(Color.BLUE);
26        canvas.drawRect(0, 0, 50, 50, mPaint);
27        canvas.restore();
28        
29        // 缩放
30        canvas.save();
31        canvas.translate(200, 100);
32        canvas.scale(2, 2);
33        mPaint.setColor(Color.GREEN);
34        canvas.drawRect(0, 0, 50, 50, mPaint);
35        canvas.restore();
36        
37        // 旋转
38        canvas.save();
39        canvas.translate(300, 100);
40        canvas.rotate(45);
41        mPaint.setColor(Color.YELLOW);
42        canvas.drawRect(0, 0, 50, 50, mPaint);
43        canvas.restore();
44        
45        // 剪切
46        canvas.save();
47        canvas.translate(400, 100);
48        canvas.clipRect(0, 0, 100, 100);
49        mPaint.setColor(Color.CYAN);
50        canvas.drawRect(0, 0, 200, 200, mPaint);
51        canvas.restore();
52        
53        // 路径绘制
54        canvas.save();
55        canvas.translate(50, 200);
56        Path path = new Path();
57        path.moveTo(0, 0);
58        path.lineTo(50, 50);
59        path.lineTo(100, 0);
60        path.close();
61        mPaint.setColor(Color.MAGENTA);
62        canvas.drawPath(path, mPaint);
63        canvas.restore();
64    }
65}

在这个自定义控件中,我们使用了Canvas的各种变换和操作来绘制不同效果的图形,展示了Canvas强大的绘图能力和灵活性。通过这种方式,你可以创建出非常复杂且动态的用户界面组件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1903922.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

增强安全防护,解读智慧校园系统的登录日志功能

在构建智慧校园系统时,登录日志功能扮演着不可或缺的角色,它不仅是系统安全的守护者,也是提升管理效率和确保合规性的有力工具。这一机制详细记录每次登录尝试的方方面面,涵盖了时间戳、用户身份、登录来源的IP地址乃至使用的设备…

python脚本“文档”撰写——“诱骗”ai撰写“火火的动态”python“自动”脚本文档

“火火的动态”python“自动”脚本文档,又从ai学习搭子那儿“套”来,可谓良心质量👍👍。 (笔记模板由python脚本于2024年07月07日 15:15:33创建,本篇笔记适合喜欢钻研python和页面源码的coder翻阅) 【学习的细节是欢悦…

Python遥感开发之批量对TIF数据合并

Python遥感开发之批量对TIF数据合并 1 原始数据展示2 按照年份合成春夏秋冬季节数据3 完整代码实现 前言:通常对遥感数据按照月和年或者季节进行分析,我们需要对我们下载的8天或者16天数据按照需求进行合并,对数据的合并一般可以采取均值法、…

移动校园(5):课程表数据获取及展示

首先写下静态页面,起初打算做成一周的课表,由于是以小程序的形式展现,所以显示一周的话会很拥挤,所以放弃下面的方案,改作一次显示一天 改后结果如下,后期还会进行外观优化 真正困难的部分是数据获取 大家大…

高德地图 key 和安全密钥使用

参考高德地图:JS API 安全密钥使用 高德地图 key 和安全密钥使用 一、通过明文方式设置参数查看如下成功后返回的信息 二、通过代理服务器转发实验:通过本地地址转发返回错的错误信息,如下通过正确的项目的的服务地址,返回正常参数…

Flink,spark对比

三:az 如何调度Spark、Flink,MR 任务 首先,使用java编写一个spark任务,定义一个类,它有main方法,里面写好逻辑,sparkConf 和JavaSparkContext 获取上下文,然后打成一个jar包&#xf…

深度学习之网络构建

目标 选择合适的神经网络 卷积神经网络(CNN):我们处理图片、视频一般选择CNN 循环神经网络(RNN):我们处理时序数据一般选择RNN 超参数的设置 为什么训练的模型的错误率居高不下 如何调测出最优的超参数 …

Node.js介绍 , 安装与使用

1.Node.js 1 什么是Node.js 官网:https://nodejs.org/zh-cn/ 中文学习网:http://nodejs.cn/learn1.Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。 2.前端的底层 html…

C++、QT企业管理系统

目录 一、项目介绍 二、项目展示 三、源码获取 一、项目介绍 人事端: 1、【产品中心】产品案列、新闻动态的发布; 2、【员工管理】新增、修改、删除、搜索功能;合同以图片的方式上传 3、【考勤总览】根据日期显示所有员工上班、下班时间…

下载nvm 管理多个node版本并切换

nvm管理多个node版本并切换 安装nvm时不能安装任何node版本(先删除node再安装nvm),保证系统无任何node.js残留 1. 卸载node 控制面板中卸载nodejs 删除以下文件夹: C:\Program Files (x86)\Nodejs C:\Program Files\Nodejs C…

聚类分析方法(一)

目录 一、聚类分析原理(一)聚类分析概述(二)聚类的数学定义(三)簇的常见类型(四)聚类框架及性能要求(五)簇的距离 二、划分聚类算法(一&#xff0…

【matlab】状态空间模型与传递函数模型的建立与转换

目录 SISO系统 MIMO系统 状态空间模型 状态空间模型到传递函数模型的转换 传递函数模型到状态空间模型的转换 (1) 转换函数ss() (2) 规范形转换函数canon() (3) 常微分方程(传递函数)转换为状态空间模型函数dif2ss() 状态空间模型的变换 特征值、特征向量与广义特征向量的计算…

进程控制-wait和waitpid进程回收

wait 阻塞函数 函数作用: 1. 阻塞并等待子进程退出 2. 回收子进程残留资源 3. 获取子进程结束状态(退出原因) pid_t wait(int *wstatus); 返回值: ‐1 : 回收失败,已经没有子进程了 >0 : 回收子进程对应的…

线上问题---反思与回顾

线上问题一:麦哲伦2.0 人群配置不生效 发现背景:产品发现三层模型部分计划个别测试计划圈选人群特征与数仓统计数据的人群不一致,向值班人员反馈 根因定位: (1)用户配置三层模型计划时,配置单…

文心一言 VS 讯飞星火 VS chatgpt (297)-- 算法导论22.1 1题

一、给定有向图的邻接链表,需要多长时间才能计算出每个结点的出度(发出的边的条数)?多长时间才能计算出每个结点的入度(进入的边的条数)?如果要写代码,请用go语言。 文心一言: 计算出度 对于有向图的邻接链表表示&a…

rufus-4.5 制作 Clonezilla(再生龙)启动盘报syslinux-6.04下载错误

1、官网下载rufus 官网下载rufus-4.5,下载地址:https://rufus.ie/downloads/ 2、下载再生龙(Clonezilla) 下载最新版本: Clonezilla live 版本: 3.1.2-22:https://sourceforge.net/projects/clonezill…

在 Docker 容器中运行 Vite 开发环境,有这两个问题要注意

容器化开发给我们带来了很多便捷,但是在开发环境下也有一些问题要注意,如果不解决这些问题,你的开发体验不会很好。 容器启动正常,却无法访问 我们用 Docker 启动一个 Vite Vue3 项目的开发环境后,发现端口日志一切…

Springboot使用WebSocket发送消息

1. 创建springboot项目&#xff0c;引入spring-boot-starter-websocket依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>完整项目依赖 <?xml ver…

【游戏客户端】大话版本slg玩法正式上线~~

【游戏客户端】制作率土之滨Like玩法 大家好&#xff0c;我是Lampard家杰~~ 好久好久没有更新博客了&#xff0c;有不少大佬都在后台私信我催更&#xff0c;但是很悲伤这段时间都忙的不行QAQ 那在忙什么呢&#xff1f;就是在制作一个SLG类的玩法【帮派纷争】啦 &#xff0c;布…

RNN、LSTM与GRU循环神经网络的深度探索与实战

循环神经网络RNN、LSTM、GRU 一、引言1.1 序列数据的迷宫探索者&#xff1a;循环神经网络&#xff08;RNN&#xff09;概览1.2 深度探索的阶梯&#xff1a;LSTM与GRU的崛起1.3 撰写本博客的目的与意义 二、循环神经网络&#xff08;RNN&#xff09;基础2.1 定义与原理2.1.1 RNN…