【问题标题】:Weird behaviour from Interactive Line in Cavnas画布中交互式线条的奇怪行为
【发布时间】:2021-10-28 18:43:51
【问题描述】:

我创建了一条交互式线路,但这可能无关紧要。即使没有交互,这也会产生意想不到的结果:-

@Composable
fun PowerClock() {
    var dynamicAngle by remember { mutableStateOf(90f.toRadians()) }
    val angle by animateFloatAsState(targetValue = dynamicAngle)
    Canvas(
        modifier = Modifier
            .fillMaxHeight()
            .fillMaxWidth()
            .pointerInput(Unit) { //Irrelevent, the results go wrong even without invoking this at all
                coroutineScope {

                    while (true) {
//                        val touchDownPointerId = awaitPointerEventScope { awaitFirstDown().id }
                        detectDragGestures { _, dragAmount ->
                            dynamicAngle += atan(dragAmount.x / dragAmount.y)
                        }
                    }
                }
            }
    ) {
        val length = 500
        val path = Path().apply {
            moveTo(size.width / 2, size.height / 2)
            relativeLineTo(length * cos(angle), length * sin(angle))
        }

        drawPath(path, Color.Blue, style = Stroke(10f))
    }
}

这是一个预览,

Cavnas 描绘的一个有趣的行为是,看看我的实现,角度应该根据xy 的变化而变化,对吧?但实际上, y 被忽略了。我已经测试过了。

这是Cavnas 中的错误还是我执行错误?

【问题讨论】:

  • 我将删除它。我从来没有不尊重任何人的意思,但也许我们无法在网上判断语气的事实,可能会给上下文增加一些意想不到的微妙之处,无论如何,如果有人因为我而受到一点干扰或不尊重,我会感到非常内疚,所以我道歉,真诚的。
  • 我只是好奇,是什么让你写这样的东西,而不仅仅是“我做错了什么还是 Compose 错误?”

标签: android kotlin canvas android-jetpack-compose android-jetpack-compose-modifier


【解决方案1】:

我已关注this answer 并采用了 Compose 代码:

var touchPosition by remember { mutableStateOf(Offset.Zero) }
Canvas(
    modifier = Modifier
        .fillMaxHeight()
        .fillMaxWidth()
        .pointerInput(Unit) { //Irrelevent, the results go wrong even without invoking this at all
            while (true) {
                detectDragGestures { change, _ ->
                    touchPosition = change.position
                }
            }
        }
) {
    val rect = Rect(Offset.Zero, size)
    val length = 500
    val path = Path().apply {
        moveTo(rect.center.x, rect.center.y)
        val angle = (touchPosition - rect.center).let { atan2(it.y, it.x) }
        relativeLineTo(length * cos(angle), length * sin(angle))
    }

    drawPath(path, Color.Blue, style = Stroke(10f))
}

结果:

【讨论】:

  • 这几乎正是我所需要的。唯一的问题是这在很大程度上取决于触摸位置。例如,如果用户玩弄它,然后触摸其他地方,它会捕捉到那个位置。
  • 我希望将这个 Composable 粘贴到一个非常高科技的背景 Composable 上。所以我希望无论用户在哪里触摸屏幕,它应该只在用户创建时钟或计数器时钟圆周运动时移动(他们不需要直接按下在线,但线仍然会移动)。无论如何,我现在将其标记为答案,但如果可以实现,那就太好了。恐怕整个代码都需要从头开始编写,因为这完全基于触摸位置......
  • 只能根据视图中心进行角度计算。如果加上Modifier.onSizeChanged,就可以在触摸处理时使用size值来计算角度。
  • 早上好/晚上好(时区),先生。建议的解决方案非常有效和高效。我想问你是否有一种简单的方法可以使指标从特定角度开始?也就是说,在第一次合成时,这里的线从Offset.Zero 计算的角度开始。如果我想让它从 -54f 开始,那怎么能实现呢?问候,马尔斯克
  • -54f 是什么意思?度数?
猜你喜欢
  • 2018-02-10
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 2014-02-16
  • 2020-12-08
相关资源
最近更新 更多