android - 我怎样才能在android compose kotlin中进行一键拖动和多点触摸拖动

标签 android kotlin android-jetpack-compose draggable offset

我想移动 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/

相关文章:

android - 在获得两个或更多修饰符的 Jetpack compose 组件中,应该如何命名修饰符参数?

android - GridView 崩溃

java - webview 中的 Youtube 显示桌面版的 youtube

带有渐变的Android形状边框

xml - 使用 Kotlin 解析 XML?

java - 停止 SwipeRefreshLayout 刷新动画,尽管 setRefresh(false)/isRefreshing=false

android - TextField maxLength - Android Jetpack 撰写

android - 无法在 Ice Cream Sandwich 中播放 HLS 流

android - 切换到插件 android gradle 3.3 时构建项目 io.realm.DefaultRealmModule 时出错

android - 在脚手架中,错误已显示为 "No value passed for parameter ' 内容'“- 我在下面附上了快照