拖动、滑动和快速滑动

draggable 修饰符是向单一方向拖动手势的高级入口点,并且会报告拖动距离(以像素为单位)。

请务必注意,此修饰符与 scrollable 类似,仅检测手势。您需要保存状态并在屏幕上表示,例如通过 offset 修饰符移动元素:

@Composable private fun DraggableText() {  var offsetX by remember { mutableFloatStateOf(0f) }  Text(  modifier = Modifier  .offset { IntOffset(offsetX.roundToInt(), 0) }  .draggable(  orientation = Orientation.Horizontal,  state = rememberDraggableState { delta ->  offsetX += delta  }  ),  text = "Drag me!"  ) }

如果您需要控制整个拖动手势,请考虑改为通过 pointerInput 修饰符使用拖动手势检测器。

@Composable private fun DraggableTextLowLevel() {  Box(modifier = Modifier.fillMaxSize()) {  var offsetX by remember { mutableFloatStateOf(0f) }  var offsetY by remember { mutableFloatStateOf(0f) }  Box(  Modifier  .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }  .background(Color.Blue)  .size(50.dp)  .pointerInput(Unit) {  detectDragGestures { change, dragAmount ->  change.consume()  offsetX += dragAmount.x  offsetY += dragAmount.y  }  }  )  } }

通过手指按下操作拖动的界面元素

滑动

您可以使用 swipeable 修饰符拖动元素,释放后,这些元素通常朝一个方向定义的两个或多个锚点呈现动画效果。其常见用途是实现“滑动关闭”模式。

请务必注意,此修饰符不会移动元素,而只检测手势。您需要保存状态并在屏幕上表示,例如通过 offset 修饰符移动元素。

swipeable 修饰符中必须提供可滑动状态,且该状态可以通过 rememberSwipeableState() 创建和记住。此状态还提供了一组有用的方法,用于以程序化方式为锚点添加动画效果(请参阅 snapToanimateToperformFlingperformDrag),同时为属性添加动画效果,以观察拖动进度。

可以将滑动手势配置为具有不同的阈值类型,例如 FixedThreshold(Dp)FractionalThreshold(Float),并且对于每个锚点的起始与终止组合,它们可以是不同的。

为了获得更大的灵活性,您可以配置滑动越过边界时的 resistance,还可以配置 velocityThreshold,即使尚未达到位置 thresholds,velocityThreshold 仍将以动画方式向下一个状态滑动。

@OptIn(ExperimentalMaterialApi::class) @Composable private fun SwipeableSample() {  val width = 96.dp  val squareSize = 48.dp  val swipeableState = rememberSwipeableState(0)  val sizePx = with(LocalDensity.current) { squareSize.toPx() }  val anchors = mapOf(0f to 0, sizePx to 1) // Maps anchor points (in px) to states  Box(  modifier = Modifier  .width(width)  .swipeable(  state = swipeableState,  anchors = anchors,  thresholds = { _, _ -> FractionalThreshold(0.3f) },  orientation = Orientation.Horizontal  )  .background(Color.LightGray)  ) {  Box(  Modifier  .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }  .size(squareSize)  .background(Color.DarkGray)  )  } }

响应滑动手势的界面元素