如何使用 AnchoredDraggableState 制作可组合的可拖动对象?

问题描述 投票:0回答:1

我正在尝试创建一个锚定的可拖动对象,但它不起作用。这是我的代码:

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.core.tween
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.AnchoredDraggableState
import androidx.compose.foundation.gestures.DraggableAnchors
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.anchoredDraggable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.example.anchoreddraggablestateexample.ui.theme.AnchoredDraggableStateExampleTheme
import kotlin.math.roundToInt

class MainActivity : ComponentActivity() {
    @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            AnchoredDraggableStateExampleTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Box(
                        Modifier
                            .fillMaxSize()
                            .background(Color.White)
                            .padding(innerPadding)
                    ) {
                        Row(Modifier.align(Alignment.Center)) {
                            SlideToAction()
                        }
                    }
                }
            }
        }
    }
}

enum class SlideToActionAnchors {
    Start,
    End
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SlideToAction() {
    val decayAnimationSpec = rememberSplineBasedDecay<Float>()
    val dragState = remember {
        AnchoredDraggableState(
            initialValue = SlideToActionAnchors.End,
            anchors = DraggableAnchors {
                SlideToActionAnchors.Start at 0f
                SlideToActionAnchors.End at 500f
            },
            positionalThreshold = { d -> d * 0.9f},
            velocityThreshold = { Float.POSITIVE_INFINITY },
            snapAnimationSpec = tween(),
            decayAnimationSpec = decayAnimationSpec
        )
    }

    Box(
        Modifier.fillMaxWidth()
            .background(Color.Red)
    ) {
        Box(
            Modifier
                .size(80.dp)
                .background(Color.Green)
                .anchoredDraggable(
                    dragState,
                    Orientation.Horizontal,
                    enabled = true
                )
                .offset {
                    IntOffset(
                        x = dragState
                            .requireOffset()
                            .roundToInt(),
                        y = 0
                    )
                }
        )
    }
}

这是我的依赖项:

[versions]
agp = "8.1.4"
kotlin = "1.9.24"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.5"
activityCompose = "1.9.2"
composeBom = "2024.09.01"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

我在 Android Studio 中执行了“新建项目”>“空活动”并将此代码转储进去。绿色框不可拖动。

kotlin android-jetpack-compose draggable
1个回答
0
投票

您需要在容器上使用

anchoredDraggable
修饰符,而不是在要移动的可组合项上。在这方面,它的工作原理与 swipeable 修饰符类似:

需要注意的是,此修改器不会移动元素,它仅检测手势。您需要保持状态并在屏幕上表示它,例如通过偏移修改器移动元素。

此外,

offset
修饰符应位于
size
之前。

Box(
    Modifier.fillMaxWidth()
        .background(Color.Red)
        .anchoredDraggable(
            state = dragState,
            orientation = Orientation.Horizontal,
            enabled = true
        )
) {
    Box(
        Modifier
            .offset { IntOffset(dragState.requireOffset().roundToInt(), 0) }
            .size(80.dp)
            .background(Color.Green)
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.