Compose学习之绘制速度表盘

内心想法XX

compose已经发布好久了,还没有用过compose写过UI,之前只是在官网上了解过,看着这可组合函数嵌套,我就脑袋大,更Flutter一个德行,我的内心是抵触的,还是觉得用XML写香,抱着试一试的心态,打算用compose应用于实际项目中。(还是得多接触,多学习,真的是很香YYDS)

无图无真相

上图,测试:通过滑动slider也是安卓称ProgressBar来改变速度
在这里插入图片描述

代码部分

@Composable
    fun SpeedContent(){
    	//添加数字动画,避免速度变化过于突兀
        var mytargetValue by remember { mutableStateOf(0) }
        val progressInt: Int by animateIntAsState(targetValue = mytargetValue)
        Column(modifier = Modifier
            .background(color = Color.White)
            .fillMaxSize(),
            verticalArrangement = Arrangement.Bottom,
            horizontalAlignment = Alignment.CenterHorizontally) {
            Slider(value = mytargetValue.toFloat(),
                onValueChange = {
                    mytargetValue = it.toInt() },
                modifier = Modifier.fillMaxWidth(),
                valueRange = 0f..180f)
            SpeederMeter(progressInt)
        }
    }

具体实现

@OptIn(ExperimentalTextApi::class)
@Composable
fun SpeederMeter(speedNum: Int,modifier: Modifier = Modifier
    .width(220.dp)
    .height(120.dp)
    .background(color = Color.White)){
    val centerPointColor = Color.Blue
    val colorCenterPoint1 = Color(0xFF000000)
    val colorCenterPoint2 = Color(0xFFEE3E07)
    val mersure = rememberTextMeasurer()
    fun getPointX(centerX:Float,angle:Int,circleRdius:Float,step:Int):Float{
        val angles = (angle*step).toDouble()
        val angle = Math.toRadians(angles)
        return centerX - cos(angle).toFloat()*(circleRdius)
    }

    fun getPointY(centerY:Float,angle:Int,circleRdius:Float,step:Int):Float{
        val angles = (angle*step).toDouble()
        val angle = Math.toRadians(angles)
        return centerY- sin(angle).toFloat()*(circleRdius)
    }
    val myUnit = "KM/H"
    val speedTextList = Array(7){(it*20).toString()}
    Box(modifier,
        contentAlignment = Alignment.BottomCenter
    ) {
        Canvas(modifier, onDraw = {
            val centerX = size.width/2
            val bottomY = size.height-50
            val myColorStops = arrayOf(0.0f to Color.White,1.0f to Color.Black)
            //画指针底座
            drawCircle(
                brush = Brush.radialGradient(colorStops = myColorStops),
                radius = 30f,
                center = Offset(centerX,bottomY+15.dp.value),
            )
            drawCircle(
                color = Color.White,
                radius = 23f,
                center = Offset(centerX,bottomY+15.dp.value)
            )
            drawCircle(
                color = Color.Red,
                radius = 20f,
                center = Offset(centerX,bottomY+15.dp.value)
            )
            //画单位
            drawText(
                textMeasurer = mersure,
                text = myUnit,
                style = TextStyle(color = Color.Black, fontSize = 12.sp, fontWeight = FontWeight(20), fontFamily = FontFamily.Serif),
                topLeft = Offset(centerX-50.dp.value,bottomY-90)
            )
            //画刻度
            repeat(61){
                val fontWeights = if( it%5==0){
                    if(it%10==0){
                        7f
                    }else{
                        4f
                    }
                }else{
                    2f
                }
                val lengths = if(it%5==0){
                    if(it%10==0){
                        25
                    }else{
                       22
                    }
                }else{
                    20
                }
                drawLine(
                    color = Color.Black,
                    start = Offset(
                        getPointX(centerX,it,bottomY,3),
                        getPointY(centerX,it,bottomY,3)
                    ),
                    end = Offset(
                        getPointX(centerX,it,bottomY-lengths,3),
                        getPointY(centerX,it,bottomY-lengths,3)
                    ),
                    strokeWidth = fontWeights,
                    cap = StrokeCap.Round
                )
            }
            //画数字
            repeat(speedTextList.size){
                val myTopLeft = Offset(
                    getPointX(centerX,it,bottomY-70,30)-25.dp.value,
                    getPointY(bottomY,it,bottomY-70,30))
                val colorType = if(it > 4){
                    Color.Red
                }else{
                    Color.Black
                }
                drawText(
                    textMeasurer = mersure,
                    text = speedTextList[it],
                    topLeft =myTopLeft,
                    style = TextStyle(colorType, fontSize = 11.sp, fontFamily = FontFamily.Serif)
                )
            }
            //画指针
            drawLine(
                color = Color.Red,
                start = Offset(
                    getPointX(centerX,speedNum,bottomY-30,1),
                    getPointY(centerX,speedNum,bottomY-30,1)
                ),
                end = Offset(
                    getPointX(centerX,speedNum,0f,1),
                    getPointY(centerX,speedNum,0f,1)
                ),
                strokeWidth = 15f,
                cap = StrokeCap.Round

            )
        })


    }

}

Compose还是蛮香的,用了就回不去了<捂脸>,只是这个代码的可读性没有Java的好。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

广州华锐互动:办税服务厅税务登记VR仿真体验让税务办理更加灵活高效

在数字化世界的今天&#xff0c;我们正在见证各种业务过程的转型&#xff0c;而税务办理也不例外。最近&#xff0c;一种全新的交互方式正在改变我们处理税务的方式&#xff1a;虚拟现实&#xff08;VR&#xff09;。 首先&#xff0c;用户需要戴上虚拟现实头显&#xff0c;然后…

Antv/G2 柱状图添加自定义点击事件

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>柱状图点击事件</title></head><body><div id"container" /><script src"https://gw.alipayobjects.com/os/lib/antv/g2/4.2.8/…

每日一练 | 华为认证真题练习Day131

1、某台路由器输出信息如下&#xff0c;下列说法正确的有&#xff1f;&#xff08;多选&#xff09; A. 本路由器是DR B. 路由器Router ID为10.0.1.1 C. 路由器Router ID为10.0.2.2 D. 本路由器的接口地址为10.0.12.2 2、以下那条命令可以开启路由器接口的DHCP中继功能&…

TS7031: Binding element ‘role‘ implicitly has an ‘any‘ type.

文章 前言错误场景问题分析解决方案后言 前言 ✨✨ 他们是天生勇敢的开发者&#xff0c;我们创造bug&#xff0c;传播bug&#xff0c;毫不留情地消灭bug&#xff0c;在这个过程中我们创造了很多bug以供娱乐。 前端bug这里是博主总结的一些前端的bug以及解决方案&#xff0c;感兴…

就近值 reduce用法 时间戳与时间点对比循环查找

后台接口返回的13为时间戳 需要与数据data的time做对比&#xff0c;查找出最近的值 data的数据结构如下&#xff1a; 将&#xff1a;改为空格&#xff0c;变成数字之间的对比 //查找最近的时间getNearestTime(timestamp, data) {let date new Date(timestamp)let h date.ge…

windows c++开发

一 安装 离线MSDN MSDN:microsoft developer network ,微软向开发人员提供的一套帮助系统。 运行vs 2017 -》运行 vs studio installer ->点击修改-》单个组件-》代码工具-》help viewer-> 安装完后&#xff0c;启动vs 在“帮助”菜单&#xff0c;“设置帮助首选项…

使用Kohya_ss训练Stable Diffusion Lora

Stable Diffusion模型微调方法 Stable Diffusion主要有 4 种方式&#xff1a;Dreambooth, LoRA, Textual Inversion, Hypernetworks。 Textual Inversion &#xff08;也称为 Embedding&#xff09;&#xff0c;它实际上并没有修改原始的 Diffusion 模型&#xff0c; 而是通过…

Sonar生成PDF错误Can‘t get Compute Engine task status.Retry..... HTTP error: 401

报错及修改&#xff1a; 报错&#xff1a;INFO: Can’t get Compute Engine task status.Retry… org.sonarqube.ws.connectors.ConnectionException: HTTP error: 401, msg: , query: org.apache.commons.httpclient.methods.GetMethod7a021f49 ERROR: Problem generating PD…

Python-pptx教程之二操作已有PPT模板文件

文章目录 简单的案例找到要修改的元素修改幻灯片中的文本代码使用示例 修改幻灯片的图片代码使用示例 删除幻灯片代码使用示例 获取PPT中所有的文本内容获取PPT中所有的图片总结 在上一篇中我们已经学会了如何从零开始生成PPT文件&#xff0c;从零开始生成较为复杂的PPT是非常消…

基于边缘智能网关的冬季管网智能监测应用

随着我国北方全面进入到冬季&#xff0c;多日以来严寒、降雪天气频发&#xff0c;民生基础设施也迎来冬季考验。尤其是民众生活仰赖的水、电、气管网&#xff0c;面临极端冰雪天气时易存在各种风险&#xff0c;包括管道水/气泄露损耗、低温冻裂、积雪压塌压损、冻结受阻等。 针…

前端常用的几种加密方法

文章目录 前端常用的几种加密方法md5 加密(不可逆)base64 位加密(可加密可解密)RSA 加密(公钥加密&#xff0c;私钥解密)AES 加密(需要密钥才能解密)CryptoJS 常用的加密方式--demo ✒️总结 前端常用的几种加密方法 在信息安全越来越受重视的今天&#xff0c;JS 安全一直是前端…

无需API实现MySQL与巨量引擎的对接

通过数环通&#xff0c;您可以使用不到几分钟的时间即可实现MySQL与巨量引擎的对接与集成&#xff0c;从而高效实现工作流程自动化&#xff0c;降本增效&#xff01; 1.产品介绍 巨量引擎是字节跳动旗下的营销服务品牌&#xff0c;它整合了字节跳动旗下的产品及海量内容&#…

asp.net购物网站源码-系统销售毕业设计

采用典型的三层架构进行开发&#xff0c;包含购物车、登陆注册、个人中心、留言板、新闻系统&#xff0c;前台页面、后台管理等主要技术&#xff1a;基于asp.net架构和sql server数据库 功能模块&#xff1a; 本源码是一个三层购物网站源码&#xff0c;功能齐全&#xff0c;界面…

【PyQt小知识 - 4】:QGroupBox分组框控件 - 边框和标题设置

QGroupBox QGroupBox 是 PyQt 中的一个小部件&#xff0c;用于创建一个带有标题的组框。 可以使用 QGroupBox 将相关控件分组并添加一个标题。 以下是一个使用 QGroupBox 的示例代码&#xff08;示例一&#xff09;&#xff1a; from PyQt5.QtWidgets import * import sysa…

Linux_虚拟机常用目录汇总

根目录&#xff08;cd /&#xff09;&#xff1a;/ 表示根目录&#xff0c;cd和 / 之间有个空格&#xff01; 用户目录&#xff08;cd ~&#xff09;&#xff1a;~ 表示用户目录&#xff0c;也称为家目录。cd 和 ~ 之间有个空格&#xff01; 当前路径&#xff1a;执行 pwd 指令…

linux运行java程序

这个帖子实现的是linux上运行java代码 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 事情发生的原因是博洋需要知道海外城市的数量&#xff0c;我一开始准备将全量数据拉取到本地&#xff0c;用代码遍历一遍。但是打包好全量数据&…

SystemVerilog学习 (9)——随机化

目录 一、概述 二、随机化 2.1、如何简单地产生一个随机数 2.1.1 利用系统函数产生随机数 2.1.2 urandom() 2.2、什么需要随机化 2.3、随机约束 2.3.1 rand 和 randc 2.3.2 随机约束的使用 2.3.3 约束块 三、总结 一、概述 随着设计变得越来越大,要产生一个完整的激…

vivado产生报告阅读分析6-时序报告2

1、复查时序路径详情 单击“ OK ”运行报告命令后 &#xff0c; 将打开一个新窗口。这样您即可复查其中内容。在其中可查看执行选定的每种类型 (min/max/min_max ) 的分析之后所报告的 N 条最差路径。 下图显示的“Report Timing ” &#xff08; 时序报告 &#xff09; 窗口…

知识梳理到了领域榜一,意外,开心。

我的护城河 就是掌握的不断更新的技术。 一直被认可的能力。 完美的项目交付。 写的文章得到了读者们的认可。 希望我做的努力被更多的人看到。 分享的代码片可以解决他人的问题。 很惊喜&#xff0c;今早我的文章被数据结构和算法领域内容榜排到了第一名。 被认可的感觉很棒。…

基于IGT-DSER实现工业触摸屏与PLC设备之间WIFI无线通讯

本文是基于IGT-DSER系列智能网关设备实现工业触摸屏与PLC设备之间WIFI无线通讯的案例。PLC之间无线通讯的案例 网络结构如下图&#xff0c;触摸屏通过网线连接IGT-DSERWIFI智能网关&#xff0c;实现WIFI的AP功能&#xff1b;一台串口型PLC和一台网口型PLC分别通过IGT-WSER智能网…