LazyColumn의 아이템을 옆으로 스와이프하면 지워지는 기능을 구현하고 싶었다.
관련 정보를 찾아보다가 Modifier에 swipeable
이라는 것이 있길래 이것을 설정하여 스와이프를 구현하기로 했다.
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun TodoRow(
todo: Todo,
onCheckCompleted: (Todo) -> Unit
) {
// swipe 상태 저장할 State 변수
val swipeableState = androidx.compose.material.rememberSwipeableState(initialValue = 0)
// 앵커로 사용할 위치
val point = LocalDensity.current.run { LocalConfiguration.current.screenWidthDp.dp.toPx() }
// 위치 to 상태
val anchors = mapOf(0f to 0, -point to 1)
if (swipeableState.isAnimationRunning) {
DisposableEffect(Unit) {
onDispose {
// -point로 설정한 앵커에 도달하면 currentValue가 1이 됨
if (swipeableState.currentValue == 1) {
// 애니메이션이 끝나고 실행될 코드
}
}
}
}
// Box 안의 Content가 Swipe 됨
Box(
Modifier
.fillMaxWidth()
.swipeable(
state = swipeableState,
orientation = Orientation.Horizontal,
anchors = anchors,
thresholds = { _, _ -> FractionalThreshold(0.8f) },
velocityThreshold = 1000.dp
)
) {
// Content
Card(
modifier = Modifier
.offset {
// swipe했을 때 위치가 움직이도록 offset 설정
IntOffset(swipeableState.offset.value.roundToInt(), 0)
}
.fillMaxWidth()
.padding(vertical = 4.dp),
shape = RoundedCornerShape(16.dp)
) {
// Card 위에 표시될 Composable들...
}
}
}
코드 정리가 필요할 것 같지만 일단 되는대로 구현했다.
스와이프 되었으면 하는 컴포저블을 Box로 감싸고, 해당 Box에 Modifier.swipeable을 적용했다.
swipeable의 인자는 차례대로 다음과 같다(이 외에도 더 존재함).
state
- rememberSwipeableState로 얻은 SwipeableState를 넘긴다. orientation
- 스와이프 할 방향 지정.anchors
- 앵커로 지정할 화면 위치(px값)와 해당 위치에 도달했을 때의 상태를 묶은 Map을 넘긴다.thresholds
- 특정한 위치까지 스와이프 하지 않으면 원래 상태로 돌아오는 위치를 지정할 수 있다.velocityThreshold
- 지정한 위치까지 스와이프 하지 않아도 특정 빠르기만큼 스와이프하면 스와이프되도록 하는 속도값(dp)을 지정할 수 있다. 그리고 swipeable
에 사용할 변수들을 상단에 정의했다.
swipeableState
의 initialValue
나 anchors
에 저장하고 있는 상태에 해당하는 값은 꼭 Int
값으로 하지 않고 원하는 타입으로 지정할 수 있다.
본인은 스와이프 했을 때 화면 밖까지 이동해서 사라졌으면 해서 현재 화면의 크기를 음수로 바꾼 값을 앵커로 사용하고, 해당 위치에서 swipeableState
의 currentValue
가 1이 되도록 저장했다.
변수들 밑의 if
문은 애니메이션이 끝났을 때 동작되는 코드이다.. (참고한 글)
마지막으로 스와이프 되었으면 하는 컴포저블의 offset
을 swipeableState
의 offset
으로 설정해주면 된다.
여담: 얼레벌레 얼추 구현해놓고 SwipeToDismiss
라는 컴포저블이 있다는걸 발견했다... 구현한게 아까워서 글로 남김...
참조한 글