Jetpack Compose初体验之自定义图表 您所在的位置:网站首页 yb125t-10f Jetpack Compose初体验之自定义图表

Jetpack Compose初体验之自定义图表

2023-04-11 05:34| 来源: 网络整理| 查看: 265

开发项目的时候,难免会遇到原生控件无法满足,需要自定义的情况,今天通过绘制几个图表来练习一下Jetpack Compose 中的自定义View。

线形图

绘制原理和之前xml中一样,只不过实现的方式变了一些,比之前简单了很多,比如下面通过path来绘制线形图。构建好path之后,直接在Canvas中绘制就OK了。

如果想要对图标进行双指缩放,可以通过Modifier.graphicsLayer().transformable()来监听手势。通过rememberTransformableState来监听手指缩放的大小然后将返回值赋值给相应的变量就可以啦

完整代码:

data class Point(val X: Float = 0f, val Y: Float = 0f) @Composable fun LineChart() { //用来记录缩放大小 var scale by remember { mutableStateOf(1f) } val state = rememberTransformableState { zoomChange, panChange, rotationChange -> scale*=zoomChange } val point = listOf( Point(10f, 10f), Point(50f, 100f), Point(100f, 30f), Point(150f, 200f), Point(200f, 120f), Point(250f, 10f), Point(300f, 280f), Point(350f, 100f), Point(400f, 10f), Point(450f, 100f), Point(500f, 200f) ) val path = Path() for ((index, item) in point.withIndex()) { if (index == 0) { path.moveTo(item.X*scale, item.Y) } else { path.lineTo(item.X*scale, item.Y) } } val point1 = listOf( Point(10f, 210f), Point(50f, 150f), Point(100f, 130f), Point(150f, 200f), Point(200f, 80f), Point(250f, 240f), Point(300f, 20f), Point(350f, 150f), Point(400f, 50f), Point(450f, 240f), Point(500f, 140f) ) val path1 = Path() path1.moveTo(point1[0].X*scale, point1[0].Y) path1.cubicTo(point1[0].X*scale, point1[0].Y, point1[1].X*scale, point1[1].Y, point1[2].X*scale, point1[2].Y) path1.cubicTo(point1[3].X*scale, point1[3].Y, point1[4].X*scale, point1[4].Y, point1[5].X*scale, point1[5].Y) path1.cubicTo(point1[6].X*scale, point1[6].Y, point1[7].X*scale, point1[7].Y, point1[8].X*scale, point1[8].Y) path1.cubicTo(point1[7].X*scale, point1[7].Y, point1[8].X*scale, point1[8].Y, point1[9].X*scale, point1[9].Y) Canvas( modifier = Modifier .fillMaxWidth() .height(120.dp) .background(Color.White) //监听手势缩放 .graphicsLayer( ).transformable(state) ) { //绘制 X轴 Y轴 drawLine( start = Offset(10f, 300f), end = Offset(10f, 0f), color = Color.Black, strokeWidth = 2f ) drawLine( start = Offset(10f, 300f), end = Offset(510f, 300f), color = Color.Black, strokeWidth = 2f ) //绘制path drawPath( path = path, color = Color.Blue, style = Stroke(width = 2f) ) drawPath( path = path1, color = Color.Green, style = Stroke(width = 2f) ) } }柱状图

下面来绘制柱状图,绘制很简单,直接根据坐标绘制矩形就可以了。Jetpack Compose中的绘制矩形的API跟之前XML中的API不大一样,需要提供绘制的左上角和矩形的大小就可以绘制了,看一下构造函数就知道了。

然后给柱子加上点击事件,Jetpack Compose中监听点击的屏幕位置坐标使用Modifier中的pointerInput方法,然后判断点击的坐标是否在矩形的范围之内即可,下面代码中只判断了X轴 的坐标,也可以在加上Y轴的判断。

最后再给柱形图加上动画,动画使用animateFloatAsState方法,值设置为0到1代表当前绘制高度的百分比,然后绘制的时候给高度添加该百分比的值就OK了。

完整代码:

private fun identifyClickItem(points: List, x: Float, y: Float): Int { for ((index, point) in points.withIndex()) { if (x > point.X+20 && x

最后绘制一个饼图,饼图的实现方式可以通过绘制drawPath和drawArc两种方式实现,drawArc的方式简单一点。

给饼图中的每一块添加点击事件,点击事件也是在Modifier的pointerInput方法中监听点击的坐标。Math.atan2()返回从原点(0,0) 到 (x,y)的线与x轴正方向的弧度值,然后通Math.toDegrees()方法把弧度转化为角度,最后通过角度获取点击的区域。

完整代码:

private fun getPositionFromAngle(angles:List,touchAngle:Double):Int{ var totalAngle = 0f for ((i, angle) in angles.withIndex()) { totalAngle +=angle if(touchAngle


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有