Jetpack Compose:如何检测点击的饼图分段及描边宽度默认方向?
一、检测圆形/半圆内点击的弧形分段或角度
核心逻辑是通过计算点击点相对圆心的角度,匹配预先划分的分段区间,同时校验点击点是否落在弧形的描边范围内:
- 计算点击点与圆心的相对偏移,转换为0-360度的角度(注意Compose坐标系Y轴向下,需适配数学角度计算)
- 根据整圆/半圆的总角度,拆分出每个分段的角度范围
- 额外判断点击点到圆心的距离,确保在弧形的内、外半径之间,避免误判空白区域
示例实现(Jetpack Compose)
Canvas(modifier = Modifier .size(300.dp) .pointerInput(Unit) { detectTapGestures { offset -> // 圆心坐标 val center = Offset(size.width / 2, size.height / 2) // 点击点相对圆心的偏移量 val delta = offset - center // 计算角度(适配Compose坐标系,转换为0-360度) var angle = Math.toDegrees(Math.atan2(delta.y, delta.x)) if (angle < 0) angle += 360 // 假设半圆分为4个分段(0-180度,每段45度) val segmentCount = 4 val segmentAngle = 180f / segmentCount for (i in 0 until segmentCount) { val start = i * segmentAngle val end = (i + 1) * segmentAngle if (angle in start..end) { println("点击了第${i+1}个分段") break } } // 校验是否在弧形描边范围内 val arcInnerRadius = size.width / 2 - 20.dp.toPx() val arcOuterRadius = size.width / 2 val distance = delta.getDistance() if (distance in arcInnerRadius..arcOuterRadius) { // 点击点在有效弧形区域内 } } } ) { // 绘制半圆分段 val segmentCount = 4 val segmentAngle = 180f / segmentCount for (i in 0 until segmentCount) { drawArc( color = if (i%2==0) Color.Blue else Color.Gray, startAngle = i * segmentAngle, sweepAngle = segmentAngle, useCenter = false, topLeft = Offset(20.dp.toPx(), 20.dp.toPx()), size = Size(size.width - 40.dp.toPx(), size.height - 40.dp.toPx()), style = Stroke(width = 40.dp.toPx()) ) } }
二、Canvas/Composable draw Modifier描边宽度的默认方向
默认情况下,描边是居中对齐的:即描边宽度的一半绘制在路径内侧,另一半绘制在外侧。
如果需要指定描边方向,可通过Stroke的align参数调整:
StrokeAlign.Inside:描边完全绘制在路径内侧StrokeAlign.Outside:描边完全绘制在路径外侧StrokeAlign.Center(默认值):描边居中分布在路径两侧
示例代码
drawCircle( color = Color.Red, radius = 100.dp.toPx(), style = Stroke( width = 20.dp.toPx(), align = StrokeAlign.Inside // 仅在内侧绘制描边 ) )
内容的提问来源于stack exchange,提问作者Thracian
相关产品推荐
相关产品推荐

