Pointer input 게시글 시리즈
#1 개요
#1-1 공식 문서
드래그, 스와이프, 플링 | Jetpack Compose | Android Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 드래그, 스와이프, 플링 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. draggable 수정자는 동작을 한 방
developer.android.com
위 공식 문서를 나의 언어로 정리했다.
#1-2 AnchoredDraggable
Swipeable에서 AnchoredDraggable로 이전 | Jetpack Compose | Android Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. Swipeable에서 AnchoredDraggable로 이전 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 경고: 이 페이지와 여
developer.android.com
Swipeable이 AnchoredDraggable로 업그레이드되었다고 한다. 위 링크는 해당 업데이트를 전하는 페이지다.
#1-3 유튜브 영상
AnchoredDraggable에 대한 개론을 담은 공식 영상이다. 왜인지는 모르겠지만, 영상 썸네일에 안드로이드 캐릭터가 해적이 쓸 법한 안대를 쓰고 있다.
#2 드래그 (drag)
#2-1 개요
Modifier.draggable()은 컴포넌트에 드래그를 '가능하게' 한다. Modifier.draggable() 만으로 드래그가 '되는' 것은 아니다. Modifier.scrollable()과 같은 맥락이다. Modifier.scrollable()에 대해 다룬 아래 링크의 게시글을 읽으면 이해가 쉬울 것이다.
[Android] Pointer input - Scroll
#1 개요 스크롤 | Jetpack Compose | Android Developers이 페이지는 Cloud Translation API를 통해 번역되었습니다. 스크롤 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세
kenel.tistory.com
위 게시글에서, 스크롤을 '가능하게' 하는 것은 Modifier.scrollable()이었다. 그리고 스크롤이 '되게' 하는 것은 Modifier.verticalScroll() 또는 Modifier.horizontalScroll()이었다. 이와 비슷하게 드래그를 '가능하게' 하는 것은 Modifier.draggable()이다. 그리고 스크롤이 '되게' 하는 것은 detectDragGestures()다.
#2-2 Modifier.draggable()가 사용된 코드 예시
@Composable
private fun DraggableText() {
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!"
)
}
#2-3 detectDragGestures()가 사용된 코드 예시
@Composable
private fun DraggableTextLowLevel() {
Box(modifier = Modifier.fillMaxSize()) {
var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(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
}
}
)
}
}
#3 플링 (fling)
플링(fling)이란, 드래그 도중 손을 떼는 것을 의미한다. 스마트폰에서 웹 페이지를 스크롤할 때를 떠올려 보라. 손가락으로 화면을 드래그하다가 손을 갑자기 휙 떼면, 마치 스크롤에 관성이 있는 것처럼 여전히 스크롤되지 않는가? 그걸을 플링이라고 한다. 역방향으로 생각해보면, 플링은 반드시 드래그가 선행되어야 발생하는 이벤트라는 것도 알 수 있다.
#4 스와이프 (swipe)

스와이프(swipe)란, 드래그나 플링 종료 시 컴포넌트가 (프로그래머에 의해 정해진) '앵커 포인트'로 이동하는 이벤트다. 역방향으로 생각해보면, 스와이프는 반드시 드래그 또는 플링이 선행되어야 발생하는 이벤트라는 것도 알 수 있다. 스와이프 동작을 위해선 Modifier.swipeable()이 필요하다. 그러나 #1-2에서 말했듯, Swipeable는 deprecated될 예정이다. 따라서 본 게시글에선 Modifier.swipeable() 대신 Modifier.anchoredDraggable()을 사용한다.
#5 AnchoredDraggable
#5-1 개요
공식 문서에 있는 내용을 잘 읽고 소화하려했다. 하지만 늬앙스만 이해되었고 내부 기제를 정확히 이해할 순 없었다. 이런 겉핥기식 이해로는, 실제 구현을 할 수 없다. 따라서 미니 프로젝트를 통해 공식 문서의 코드를 따라해보겠다. 우선 AnchoredDraggableExample이라는 이름의 Jetpack Compose 프로젝트를 만들었다.
#5-2 기본 구조
...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
AnchoredDraggableExampleTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
SwipeableBox()
}
}
}
}
}
}
@Composable
fun SwipeableBox() {
Box(
modifier = Modifier
.width(200.dp)
.height(200.dp)
.background(Color.LightGray)
) {
Text("Swipe me")
}
}
화면 전체를 차지하는 Box()에 스와이프를 적용할 작은 Box()를 두었다.
#5-3 AnchoredDraggableState
내용 추가 예정.
'깨알 개념 > Android' 카테고리의 다른 글
[Android] App layout - Custom layouts (0) | 2025.02.27 |
---|---|
[Android] UI architecture - Phase와 State (1) | 2025.02.27 |
[Android] UI architecture - Phases (0) | 2025.02.27 |
[Android] App layout - 기초 (0) | 2025.02.27 |
[Android] Pointer input - Nested Scroll (0) | 2025.02.18 |