Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Compose绘制速度表盘

Android Compose学习之绘制速度表盘

作者:jianghe_130

这篇文章主要为大家详细介绍了Android 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的好。

到此这篇关于Android Compose学习之绘制速度表盘的文章就介绍到这了,更多相关Compose绘制速度表盘内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文