我想移动 Box 一键拖动和多点触摸拖动,但是,它只能移动多点触摸。 如何使用一个偏移变量来使用它们
@Composable
fun TransformableSample() {
// set up all transformation states
var scale by remember { mutableStateOf(1f) }
var rotation by remember { mutableStateOf(0f) }
var offset by remember { mutableStateOf(Offset.Zero) }
val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
scale *= zoomChange
rotation += rotationChange
offset += offsetChange
}
Box(
Modifier
// apply other transformations like rotation and zoom
// on the pizza slice emoji
.graphicsLayer(
scaleX = scale,
scaleY = scale,
rotationZ = rotation,
translationX = offset.x,
translationY = offset.y
)
// add transformable to listen to multitouch transformation events
// after offset
.transformable(state = state)
.background(Color.Blue)
.fillMaxSize()
)
}
最佳答案
您将需要使用 Modifier.pointerInput() combined with Modifier.graphicsLayer() 。对您来说重要的是,这将允许您用一根手指或两根手指拖动图像。它仍然会使用记住状态(尽管我通常保存这些值以及 ViewModel 中的所有数学)。这是从文档复制的代码。
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
/**
* Rotates the given offset around the origin by the given angle in degrees.
*
* A positive angle indicates a counterclockwise rotation around the right-handed 2D Cartesian
* coordinate system.
*
* See: [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
*/
fun Offset.rotateBy(angle: Float): Offset {
val angleInRadians = angle * PI / 180
return Offset(
(x * cos(angleInRadians) - y * sin(angleInRadians)).toFloat(),
(x * sin(angleInRadians) + y * cos(angleInRadians)).toFloat()
)
}
var offset by remember { mutableStateOf(Offset.Zero) }
var zoom by remember { mutableStateOf(1f) }
var angle by remember { mutableStateOf(0f) }
Box(
Modifier
.pointerInput(Unit) {
detectTransformGestures(
onGesture = { centroid, pan, gestureZoom, gestureRotate ->
val oldScale = zoom
val newScale = zoom * gestureZoom
// For natural zooming and rotating, the centroid of the gesture should
// be the fixed point where zooming and rotating occurs.
// We compute where the centroid was (in the pre-transformed coordinate
// space), and then compute where it will be after this delta.
// We then compute what the new offset should be to keep the centroid
// visually stationary for rotating and zooming, and also apply the pan.
offset = (offset + centroid / oldScale).rotateBy(gestureRotate) -
(centroid / newScale + pan / oldScale)
zoom = newScale
angle += gestureRotate
}
)
}
.graphicsLayer {
translationX = -offset.x * zoom
translationY = -offset.y * zoom
scaleX = zoom
scaleY = zoom
rotationZ = angle
transformOrigin = TransformOrigin(0f, 0f)
}
.background(Color.Blue)
.fillMaxSize()
)
关于android - 我怎样才能在android compose kotlin中进行一键拖动和多点触摸拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71274908/