#1 ๊ฐ์
#1-1 ์ด์ ๊ฒ์๊ธ
[Android] Pointer input - PointerInputChange, PointerEvent
#1 ๊ฐ์ ๋์ ์ดํดํ๊ธฐ | Jetpack Compose | Android Developers์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. ๋์ ์ดํดํ๊ธฐ ์ปฌ๋ ์ ์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ ์ธ ๋ฅผ ์
kenel.tistory.com
์ ๊ฒ์๊ธ์์ AwaitPointerEventScope()์ ๊ฐ์ฅ ๋ํ์ ์ธ ๋ฉ์๋์ธ awaitPointerEvent()์ ๋ํด ๊ฐ๋จํ ์ค๋ช
ํ๋ค. ๋ณธ ๊ฒ์๊ธ์์ awaitPointerEvent()๋ฅผ ์ ์ธํ ๋๋จธ์ง ๋ฉ์๋๋ค์ ์ค๋ช
ํ๋ค.
#1-2 ๊ณต์ ๋ฌธ์
AwaitPointerEventScope | Android Developers
androidx.appsearch.builtintypes.properties
developer.android.com
์ด ์๋ ๋ด์ฉ๋ถํด, ์์ ๊ณต์ ๋ฌธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑํ๋ค. ์์ด ๋ฅ๋ ฅ์๋ผ๋ฉด ๋ด ๊ธ๋ณด๋ค ์์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฝ๋ ํธ์ด ํจ์ฌ ์ข์ ๊ฒ์ด๋ค.
#2 ์ฉ์ด ์ ๋ฆฌ
#2-1 ์ทจ์ (Cancellation)
Pointer์ ๋์์ด ๋๊น์ง ์ํ๋์ง ์๊ณ ์ค๊ฐ์ ์คํจํจ์ ์๋ฏธ. ์ค๋งํธํฐ ํ๋ฉด ํ์ , ๊ฐ์๊ธฐ ํ ํ๋ฉด์ผ๋ก ๋๊ฐ์ง ๋ฑ์ด ์์ธ. ๋ณธ ๊ฒ์๊ธ์์ ํน๋ณํ ์ฃผํฉ์ ๊ธ์จ๋ก ํ์ํ๊ฒ ๋ค.
#2-2 ํฐ์น ๋ฏผ๊ฐ๋ (Touch Slop)
Pointer๋ฅผ ์ผ๋ง์ ๊ฑฐ๋ฆฌ๋งํผ ์์ง์ด์ผ '๋๋๊ทธ'๋ก ์ธ์ํ๋ ์ง์ ๊ธฐ์ค ๊ฐ ๋๋ ๊ทธ๋ ๊ฒ ํด์ ์ธ์๋ ๋๋๊ทธ. ๋ณธ ๊ฒ์๊ธ์์ ํน๋ณํ ๋ณด๋ผ์ ๊ธ์จ๋ก ํ๊ธฐํ๊ฒ ๋ค.
#2-3 ์๋น (Consume)
[Android] Pointer input - PointerInputChange, PointerEvent
#1 ๊ฐ์ ๋์ ์ดํดํ๊ธฐ | Jetpack Compose | Android Developers์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. ๋์ ์ดํดํ๊ธฐ ์ปฌ๋ ์ ์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ ์ธ ๋ฅผ ์ ์ฅํ๊ณ
kenel.tistory.com
์ ๊ฒ์๊ธ ์ฐธ์กฐ. ๋ณธ ๊ฒ์๊ธ์์ ํน๋ณํ ํ๋์ ๊ธ์จ๋ก ํ๊ธฐํ๊ฒ ๋ค.
#3 ๋ฉ์๋ ๋ชฉ๋ก - ๊ธฐ๋ณธ
#3-1 awaitFirstDown()
suspend fun AwaitPointerEventScope.awaitFirstDown(
requireUnconsumed: Boolean = true,
pass: PointerEventPass = PointerEventPass.Main
): PointerInputChange
์ค๋ช
'์ฒซ๋ฒ์งธ' ํฐ์น๋ฅผ ๊ธฐ๋ค๋ฆผ. '์ฒซ๋ฒ์งธ'๋ผ๋ ๋ง์ ์ด๋ค ๋งฅ๋ฝ์ผ๋ก ์ฌ์ฉ๋์๋๊ฐ? ์๋ฅผ ๋ค์ด, ์ค๋งํธํฐ ์ฌ์ฉ์๊ฐ ํ๋ฉด์ ์๊ฐ๋ฝ์ ๋๊ณ ์ด๋ฆฌ์ ๋ฆฌ ๋๋๊ทธํ๋ค๊ฐ ๋ผ์๋ค๊ณ ์น์. ์ด ๊ฒฝ์ฐ '์ฒซ๋ฒ์งธ' ํฐ์น๋ ํ๋ฉด์ ์๊ฐ๋ฝ์ ๋ ์๊ฐ์ ํฐ์น๋ฅผ ์๋ฏธํ๋ค. ํจ์๋ช
์ ์๋ 'down'์ด ์ด ์๋ฏธ๋ค. ํ๋ฉด์ ์๊ฐ๋ฝ์ ๋ด๋ ค(down)๋์ ์๊ฐ์ด๋ผ๋ ๋ฌ์์ค๋ค. requireUnconsumed๋ฅผ false๋ก ๋ช
์ํ๋ฉด, ์ด๋ฏธ ์๋น๋ '์ฒซ๋ฒ์งธ' ํฐ์น๋ ๊ฐ์งํ๋ค.
๋ฐํ
'์ฒซ๋ฒ์งธ' ํฐ์น์ ํด๋นํ๋ PointerInputChange ๋ฐํ.
#3-2 awaitLongPressOrCancellation()
suspend fun AwaitPointerEventScope.awaitLongPressOrCancellation(
pointerId: PointerId
): PointerInputChange?
์ค๋ช
๊พน ๋๋ฅด๋ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ค๋ฆผ.
๋ฐํ
๊พน ๋๋ฅด๋ ํด๋ฆญ ์ด๋ฒคํธ์ ํด๋นํ๋ PointerInputChange๋ฅผ ๋ฐํํ๋ค. ์ทจ์๋๋ฉด ๋์ null์ ๋ฐํํ๋ค.
#3-3 waitForUpOrCancellation()
suspend fun AwaitPointerEventScope.waitForUpOrCancellation(
pass: PointerEventPass = PointerEventPass.Main
): PointerInputChange?
์ค๋ช
์๊ฐ๋ฝ์ด ํ๋ฉด์์ ๋ผ์ด์ง(Up) ๊ฒ์ ๊ธฐ๋ค๋ฆผ. awaitFirstDown()์ ๋ฐ๋๋ค.
๋ฐํ
์ ์์ ์ผ๋ก ์๊ฐ๋ฝ์ด ํ๋ฉด์์ ๋ผ์ด์ก๋ค๋ฉด ํด๋น๋๋ PointerInputChange๊ฐ ๋ฐํ๋๊ณ , ์ทจ์๋๋ฉด ๋์ null์ ๋ฐํ.
#4 ๋ฉ์๋ ๋ชฉ๋ก - ๋๋๊ทธ ๊ด๋ จ
#4-1 drag()
suspend fun AwaitPointerEventScope.drag(
pointerId: PointerId,
onDrag: (PointerInputChange) -> Unit
): Boolean
์ค๋ช
ํน์ ํฌ์ธํฐ์ ๋๋๊ทธ๋ฅผ ์ถ์ . ํน์ ํฌ์ธํฐ๊ฐ ๋๋๊ทธ๋ฅผ ์ํํ ๋๋ง๋ค ํ๋ก๊ทธ๋๋จธ๊ฐ ๊ตฌํํด ๋ฃ์ onDrag() ํจ์๊ฐ ์คํ๋จ. ํฐ์น ๋ฏผ๊ฐ๋๋ฅผ ์ ๊ฒฝ ์ฐ์ง ์์ผ๋ฏ๋ก, ์์ฃผ ์ด์ง๋ง ์์ง์ฌ๋ ๊ฐ์งํจ.
๋ฐํ
null์ ๋ฐํํ์ง ์์ผ๋ฉฐ, ๋ฐ๋์ PointerInputChange ๊ฐ์ฒด๋ฅผ ๋ฐํ.
์ฉ๋ก
modifier.pointerInput(Unit) {
awaitPointerEventScope {
val down = awaitFirstDown() // '์ฒซ๋ฒ์งธ' ํฐ์น ๊ฐ์ง
drag(down.id) { change ->
println("Dragging: ${change.position}") // ํ์ฌ ํฐ์น ์ขํ ์ถ๋ ฅ
}
}
}
#4-2 verticalDrag()
suspend fun AwaitPointerEventScope.verticalDrag(
pointerId: PointerId,
onDrag: (PointerInputChange) -> Unit
): Boolean
์ค๋ช
์์ง ๋๋๊ทธ๋ง์ ๊ฐ์งํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด drag()์ ๋์ผํ๋ค.
#4-3 horizontalDrag()
suspend fun AwaitPointerEventScope.horizontalDrag(
pointerId: PointerId,
onDrag: (PointerInputChange) -> Unit
): Boolean
์ค๋ช
์ํ ๋๋๊ทธ๋ง์ ๊ฐ์งํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด drag()์ ๋์ผํ๋ค.
#4-4 awaitDragOrCancellation()
suspend fun AwaitPointerEventScope.awaitDragOrCancellation(pointerId: PointerId): PointerInputChange?
์ค๋ช
ํน์ ํฌ์ธํฐ์ '๋๋๊ทธ๊ฐ ์์๋จ'๋ฅผ ๊ฐ์ง. drag()๊ฐ ๋๋๊ทธ๊ฐ ์งํ๋๋ ์ค์ธ ํฌ์ธํฐ๋ก๋ถํฐ ์ค์๊ฐ ์์น๋ฅผ ์ถ์ ํด ์ ๋ฌ๋ฐ๋ ์ฉ๋๋ผ๋ฉด, ๋ณธ ํจ์์ธ awaitDragOrCancellation()์ ๊ทธ์ ๋๋๊ทธ๊ฐ ์์๋์์์ ๊ฐ์งํจ. ๋ฐ๋ผ์ drag()์ฒ๋ผ onDrag() ํจ์ ๋ฐ์๋ฅผ ๋ณด์ ํ์ง ์์. ํฐ์น ๋ฏผ๊ฐ๋๋ฅผ ์ ๊ฒฝ ์ฐ์ง ์์ผ๋ฏ๋ก, ์์ฃผ ์ด์ง๋ง ์์ง์ฌ๋ ๊ฐ์งํจ.
๋ฐํ
๋๋๊ทธ๊ฐ ์์๋๋ฉด ํด๋น ํฌ์ธํฐ์ PointerInputChange ๋ฐํ. ์ทจ์๋๋ฉด ๋์ null ๋ฐํ.
์ฉ๋ก
modifier.pointerInput(Unit) {
awaitPointerEventScope {
val down = awaitFirstDown() // ์ฒซ ๋ฒ์งธ ํฐ์น ๊ฐ์ง
val drag = awaitDragOrCancellation(down.id) // ๋๋๊ทธ ์์ ๊ฐ์ง (์ทจ์๋ ์๋ ์์)
if (drag != null) {
println("๋๋๊ทธ ์์๋จ: ${drag.position}")
} else {
println("๋๋๊ทธ๊ฐ ์ทจ์๋จ") // ํฐ์น๊ฐ ์ค๊ฐ์ ์ทจ์๋์์ ๊ฒฝ์ฐ
}
}
}
#4-5 awaitVerticalDragOrCancellation()
suspend fun AwaitPointerEventScope.awaitVerticalDragOrCancellation(
pointerId: PointerId
): PointerInputChange?
์ค๋ช
์์ง ๋๋๊ทธ๋ง์ ๊ฐ์งํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด awaitDragOrCancellation()์ ๋์ผํ๋ค.
#4-6 awaitHorizontalDragOrCancellation()
suspend fun AwaitPointerEventScope.awaitHorizontalDragOrCancellation(
pointerId: PointerId
): PointerInputChange?
์ค๋ช
์ํ ๋๋๊ทธ๋ง์ ๊ฐ์งํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด awaitDragOrCancellation() ์ ๋์ผํ๋ค.
#5 ๋ฉ์๋ ๋ชฉ๋ก - ํฐ์น ๋ฏผ๊ฐ๋ ๊ด๋ จ
#5-1 awaitTouchSlopOrCancellation()
suspend fun AwaitPointerEventScope.awaitTouchSlopOrCancellation(
pointerId: PointerId,
onTouchSlopReached: (change: PointerInputChange, overSlop: Offset) -> Unit
): PointerInputChange?
์ค๋ช
ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ช
์ํ ํฐ์น ๋ฏผ๊ฐ๋๋ฅผ ์ด๊ณผํด์ผ '๋๋๊ทธ'๋ผ๊ณ ์ธ์ํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด, awaitDragOrCancellation()์ ๊ฑฐ์ ๋์ผํ๋ค. ๋, awaitDragOrCancellation()์๋ ์๋ (์ฌ์ฉ์๊ฐ ํน์ ํฐ์น ๋ฏผ๊ฐ๋๋ฅผ ์ด๊ณผํ์ ๋ ํธ์ถ๋ ) ์ฝ๋ฐฑ ํจ์๋ ์กด์ฌํ๋ค.
#5-2 awaitVerticalTouchSlopOrCancellation()
suspend fun AwaitPointerEventScope.awaitVerticalTouchSlopOrCancellation(
pointerId: PointerId,
onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?
์ค๋ช
์์ง ๋๋๊ทธ๋ง์ ๊ฐ์งํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด awaitTouchSlopOrCancellation()์ ๋์ผํ๋ค.
#5-3 awaitHorizontalTouchSlopOrCancellation()
suspend fun AwaitPointerEventScope.awaitHorizontalTouchSlopOrCancellation(
pointerId: PointerId,
onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?
์ค๋ช
์ํ ๋๋๊ทธ๋ง์ ๊ฐ์งํ๋ค๋ ์ ์ ์ ์ธํ๋ฉด awaitTouchSlopOrCancellation()์ ๋์ผํ๋ค.
'๊นจ์ ๊ฐ๋ ๐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] Pointer input - Scroll (0) | 2025.02.17 |
---|---|
[Android] Pointer input - Gesture (0) | 2025.02.08 |
[Android] Pointer input - PointerInputChange, PointerEvent (0) | 2025.02.07 |
[Android] Jetpack Compose - Navigation์ Destination ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ (NavBackStackEntry. (0) | 2024.09.13 |
[Android] Jetpack Compose - Navigation ๊ธฐ์ด (0) | 2024.09.12 |