2024. 5. 14. 19:39ㆍIT/Android
<미리 보기>
<소스 코드>
<정리>
SwipeToDismissBox - 소개팅 앱 처럼 간단한 좌우 스와이프에 대한 동작만 구현한다면 괜찮은 컴포저블이지만, 스와이프 상태에 따라 출력되는 UI가 명확하게 나뉘어져 있어 스와이프 전과 후의 UI를 동시에 출력할 수 없다는 제한이 따른다.
SwipeToDismissBox 파라미터 설명.
state : 스와이프 동작의 상태를 추적.
backgroundContent : 스와이프 할 때 보여지는 컨텐츠.
enableDismissFromStartToEnd : Start(left)에서 End(right) 방향으로 Dismiss를 허용할 지에 대한 Boolean 값.
enableDismissFromEndToStart : End(right)에서 Start(left) 방향으로 Dismiss를 허용할 지에 대한 Boolean 값.
content : 스와이프 될 컨텐츠.
@Composable
@ExperimentalMaterial3Api
fun SwipeToDismissBox(
state: SwipeToDismissBoxState,
backgroundContent: @Composable RowScope.() -> Unit,
modifier: Modifier = Modifier,
enableDismissFromStartToEnd: Boolean = true,
enableDismissFromEndToStart: Boolean = true,
content: @Composable RowScope.() -> Unit,
) {}
SwipeToDismissBoxState - 스와이프의 방향 및 진행 상태를 추적하는 객체로, 보통 rememberSwipeToDismissBoxState() 함수를 사용하여 객체를 생성하는데 이는 리컴포지션이 발생해도 상태의 보존이 가능하다.
rememberSwipeToDismissBoxState 파라미터 설명.
initialValue : 스와이프가 되지 않은 상태의 초기 값.
confirmValueChange : 스와이프 동작을 완료하고 상태를 변경할 때 호출되는 콜백 함수로, 상태에 따른 동작을 정의할 수 있다.
positionalThreshold : 스와이프 동작을 감지하기 위한 임계값으로 설정한 임계값을 초과할 때만 스와이프 동작이 감지되는데, 보통 SwipeToDismissBoxDefaults.positionalThreshold를 사용하여 설정한다.
@Composable
@ExperimentalMaterial3Api
fun rememberSwipeToDismissBoxState(
initialValue: SwipeToDismissBoxValue = SwipeToDismissBoxValue.Settled,
confirmValueChange: (SwipeToDismissBoxValue) -> Boolean = { true },
positionalThreshold: (totalDistance: Float) -> Float =
SwipeToDismissBoxDefaults.positionalThreshold,
): SwipeToDismissBoxState {}
참조 : https://medium.com/@shivathapa.dev/apply-swipetodismissbox-in-android-jetpack-compose-4b9cec46355e
SwipeToDismissBox 컴포저블 없이 Swipe to reveal 구현.
스와이프를 설정할 컴포저블에 Modifier.pointerInput()의 detectHorizontalDragGestures를 호출하여 수평 드래그를 감지하고 해당 드래그에 대한 동작을 설정한다. 람다의 dragAmount는 드래그의 길이를 나타내어 왼쪽으로 드래그 하면 음수를, 오른쪽으로 드래그하면 양수가 전달된다. 이를 사용하여 특정 길이의 드래그에 대한 동작을 설정할 수 있다. 아래의 코드에서는 드래그된 카드를 저장하는 리스트를 정의하여 오른쪽으로 드래그되는 카드의 정보를 리스트에 저장(onExpand)하고 왼쪽으로 드래그되는 카드의 정보를 리스트에서 제거(onCollapse)하는 동작을 지정하였다. 이렇게 드래그된 카드의 정보가 담긴 리스트는 카드 각각의 애니메이션 활성화 기준이 된다.
Card(
modifier = modifier
.fillMaxWidth()
.padding(
horizontal = dimensionResource(R.dimen.swipe_ui_padding_horizontal),
vertical = dimensionResource(R.dimen.swipe_ui_padding_vertical)
)
.height(cardHeight)
.offset(offsetTransition.value.roundToInt().dp, 0.dp)
.pointerInput(Unit) {
detectHorizontalDragGestures { _, dragAmount ->
when {
dragAmount >= MIN_DRAG_AMOUNT -> onExpand()
dragAmount < -MIN_DRAG_AMOUNT -> onCollapse()
}
}
},
colors = CardDefaults.cardColors(cardBgColor.value),
elevation = CardDefaults.cardElevation(cardElevation.value),
shape = RoundedCornerShape(0.dp)
) {...}
rememberTransition()를 호출하고 MutableTransitionState의 생성자로 초기 값을 전달하여 트랜지션 상태 객체를 생성한다. 이 초기 값은 애니메이션이 활성화가 되지 않는 기준이 되며, 활성화가 되는 기준은 targetState 프로퍼티에 값을 전달하여 지정할 수 있다. 생성된 상태 객체를 사용하여 트랜지션 객체를 생성하는데, 이는 여러 애니메이션을 하나로 묶어 실행할 수 있도록 한다. 트랜지션 객체를 사용하여 생성하는 애니메이션은 파라미터 transitionSpec에 효과를, targetValueByState에 상태에 따른 변경 사항을 전달하여 완성한다. 아래의 코드에서는 위에서 완성된 드래그된 카드의 리스트를 사용하여 해당 카드가 리스트에 포함되었는지의 유무에 따라 Boolean값을 전달받아 상태 객체를 생성하였고, 여러 애니메이션(색, 위치, 명암)을 생성하면서 tween효과를 설정했다. 생성된 애니메이션은 Card의 Modifier.offset, colors, elevation에 각각 삽입하여 완성시켰다.
val transitionState = rememberTransition(
transitionState = MutableTransitionState(initialState = isSwiped)
.apply { targetState = !isSwiped })
val transition = updateTransition(transitionState, "cardTransition")
val cardBgColor = transition.animateColor(
label = "cardBgColorTransition",
transitionSpec = { tween(durationMillis = ANIMATION_DURATION) },
targetValueByState = {
if (it.currentState) Color.Yellow else Color.Gray
}
)
val offsetTransition = transition.animateFloat(
label = "cardOffsetTransition",
transitionSpec = { tween(durationMillis = ANIMATION_DURATION) },
targetValueByState = { if (it.currentState) cardOffset else 0f },
)
val cardElevation = transition.animateDp(
label = "cardElevation",
transitionSpec = { tween(durationMillis = ANIMATION_DURATION) },
targetValueByState = { if (it.currentState) 40.dp else 2.dp }
)
참조 : https://proandroiddev.com/swipe-to-reveal-in-jetpack-compose-6ffa8928a4c2
'IT > Android' 카테고리의 다른 글
Add notifications to your app/About notifications (0) | 2024.05.21 |
---|---|
Core areas/Permissions/Request app permissions/Request runtime permissions (0) | 2024.05.21 |
Android - Firebase Realtime Database Work with Lists (0) | 2024.05.08 |
Android - Firebase Realtime Database Read and Write (0) | 2024.05.07 |
Android - Firebase Realtime Database Structure (0) | 2024.05.07 |