Compose Pointer Input
Modifier에는 사용자의 터치, 입력 등을 감지할 수 있는 API가 존재한다.
clickable
clickable
Modifier는 Composable을 클릭하였을 때 동작을 정의할 수 있는 가장 쉬운(higher level) API이다.
@Composable
fun ClickableSample() {
val count = remember { mutableStateOf(0) }
// content that you want to make clickable
Text(
text = count.value.toString(),
modifier = Modifier.clickable { count.value += 1 }
)
}
pointerInput
pointerInput
Modifier는 다양한 터치 관련 제스처를 인식하는 데 사용할 수 있다.
Modifier.pointerInput(Unit) {
detectTapGestures(
onPress = { /* Called when the gesture starts */ },
onDoubleTap = { /* Called on Double Tap */ },
onLongPress = { /* Called on Long Press */ },
onTap = { /* Called on Tap */ }
)
}
verticalScroll
, horizontalScroll
내부 컨텐츠가 Composable의 최대 크기 constraints보다 클 경우 스크롤할 수 있는 방법을 제공한다.
@Composable
fun ScrollBoxes() {
Column(
modifier = Modifier
.background(Color.LightGray)
.size(100.dp)
.verticalScroll(rememberScrollState())
) {
repeat(10) {
Text("Item $it", modifier = Modifier.padding(2.dp))
}
}
}
ScrollState
를 통해 verticalScroll
, horizontalScroll
의 스크롤 상태를 변경하거나 현재 스크롤 위치 등을 가져올 수 있다.
// Smoothly scroll 100px on first composition
val state = rememberScrollState()
LaunchedEffect(Unit) { state.animateScrollTo(100) }
scrollable
verticalScroll
, horizontalScroll
과 달리 scrollable
은 스크롤 동작을 감지하지만 내부 콘텐츠를 변화시키지 않는다. rememberScrollableState
를 적용하여 스크롤 동작에 따라 내부 콘텐츠를 어떻게 변화시켜야 할 지 정의할 수 있다.
@Composable
fun ScrollableSample() {
// actual composable state
var offset by remember { mutableStateOf(0f) }
Box(
Modifier
.size(150.dp)
.scrollable(
orientation = Orientation.Vertical,
// Scrollable state: describes how to consume
// scrolling delta and update offset state = rememberScrollableState { delta ->
offset += delta
delta
}
)
.background(Color.LightGray),
contentAlignment = Alignment.Center
) {
Text(offset.toString())
}
}
draggable
드래그를 감지하는 Modifier이다. scrollable
와 마찬가지로 동작만을 감지하며 변화는 rememberDraggableState
를 이용하여 수동으로 변화를 주어야 한다.
var offsetX by remember { mutableStateOf(0f) }
Text(
modifier = Modifier
.offset { IntOffset(offsetX.roundToInt(), 0) }
.draggable(
orientation = Orientation.Horizontal,
state = rememberDraggableState { delta ->
offsetX += delta
}
),
text = "Drag me!"
)
swipeable
스와이프(드래그하다가 손을 뗀 지점이 일정 임계치를 넘어가면 둘 이상의 앵커 중 하나를 향해 애니메이션) 동작을 처리할 때 사용한다. 이 또한 동작만 감지하며 rememberSwipeableState()
를 사용하여 만들고 저장할 수 있다.
@Composable
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)
)
}
}