터치스크린이 불편할 때 손목 동작을 사용하면 한 손으로 빠르게 앱과 상호작용할 수 있습니다.
예를 들어 사용자가 한 손에 물컵을 들고 다른 한 손으로 알림을 스크롤할 수 있습니다. 손목 동작의 다른 사용 사례는 다음과 같습니다.
- 조깅 앱에서 걸음 수, 경과 시간, 현재 속도를 보여주는 세로 화면 탐색
- 여행 앱에서 항공편 및 게이트 정보 스크롤
- 뉴스 앱에서 기사 스크롤
시계 기기에서 손목 동작을 검토하려면 설정 > 고급 기능 > 동작 > 손목 동작 사용을 선택하여 동작이 켜져 있는지 확인합니다. 그런 다음 튜토리얼 시작을 선택하여 시계에서 동작 튜토리얼을 완료합니다.
참고: 손목 흔들기는 시스템 전체 뒤로 또는 실행취소 동작이므로 앱에서 맞춤설정할 수 없습니다.
손목 동작은 이 가이드에 설명된 대로 다음과 같은 방식으로 사용할 수 있습니다.
각 손목 동작은 다음 표에 나와 있는 것처럼 KeyEvent
클래스의 int
상수로 매핑됩니다.
동작 | 키 이벤트 | 설명 |
---|---|---|
손목을 바깥쪽으로 휙 돌리기 |
KEYCODE_NAVIGATE_NEXT
|
이 키 코드를 실행하면 다음 항목으로 이동합니다. |
손목을 안쪽으로 휙 돌리기 |
KEYCODE_NAVIGATE_PREVIOUS
|
이 키 코드를 실행하면 이전 항목으로 이동합니다. |
손목 동작을 지원하는 곡선형 레이아웃 사용
WearableRecyclerView
클래스는 목록에 곡선형 레이아웃을 제공하고 손목 동작을 자동으로 지원합니다. 이 클래스에는 뷰에 포커스가 있을 때 손목 동작이 발생하는 경우를 위한 미리 정의된 동작이 있습니다. WearableRecyclerView
클래스 사용에 관한 자세한 내용은 Wear OS에서 목록 만들기를 참고하세요. 또한 이 가이드의 권장사항 섹션을 참고하세요.
참고: WearableRecyclerView
클래스는 웨어러블 지원 라이브러리에서 지원 중단된 유사 클래스를 대체합니다.
WearableRecyclerView
를 사용하더라도 KeyEvent
클래스의 상수를 사용하고 싶을 수 있습니다. 미리 정의된 작업은 WearableRecyclerView
를 서브클래스로 분류하고 onKeyDown()
콜백을 다시 구현하여 재정의할 수 있습니다. 동작은 setEnableGestureNavigation(false)
를 사용하여 완전히 중지할 수 있습니다.
자세한 내용은
키보드 작업 처리를 참고하세요.
키 이벤트 직접 사용
WearableRecyclerView
이외의 키 이벤트를 사용하여 동작 이벤트에 대한 응답으로 새 작업을 트리거할 수 있습니다. 무엇보다도 이러한 동작 이벤트는 기기가 활성 모드일 때 인식되며 모든 키 이벤트와 동일한 방식으로 전달됩니다.
View
또는 Activity
와 같은 사용자 상호작용과 관련되고
KeyEvent.Callback
을 구현하는 클래스는 다른 키 이벤트에 나열할 수 있는 것처럼 손목 동작과 관련된 키 이벤트를 수신 대기할 수 있습니다. Android 프레임워크는 키 이벤트에 포커스가 있는 View
또는 Activity
를 호출합니다. 동작의 경우 동작이 발생할 때 onKeyDown()
메서드 콜백이 호출됩니다.
예를 들어 앱은 다음과 같이 KeyEvent.Callback
을 구현하는 View
또는 Activity
에서 사전 정의된 작업을 재정의할 수 있습니다.
Kotlin
class GesturesActivity : Activity() { /* KeyEvent.Callback */ override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_NAVIGATE_NEXT -> // Do something that advances a user View to the next item in an ordered list. moveToNextItem() KeyEvent.KEYCODE_NAVIGATE_PREVIOUS -> // Do something that advances a user View to the previous item in an ordered list. moveToPreviousItem() else -> { // If you did not handle it, let it be handled by the next possible element as determined // by the Activity. super.onKeyDown(keyCode, event) } } } /** Shows the next item in the custom list. */ private fun moveToNextItem(): Boolean { ... // Return true if handled successfully, otherwise return false. return false } /** Shows the previous item in the custom list. */ private fun moveToPreviousItem(): Boolean { ... // Return true if handled successfully, otherwise return false. return false } }
Java
public final class GesturesActivity extends Activity { @Override /* KeyEvent.Callback */ public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_NAVIGATE_NEXT: // Do something that advances a user View to the next item in an ordered list. return moveToNextItem(); case KeyEvent.KEYCODE_NAVIGATE_PREVIOUS: // Do something that advances a user View to the previous item in an ordered list. return moveToPreviousItem(); } // If you did not handle it, let it be handled by the next possible element as determined by the Activity. return super.onKeyDown(keyCode, event); } /** Shows the next item in the custom list. */ private boolean moveToNextItem() { boolean handled = false; ... // Return true if handled successfully, otherwise return false. return handled; } /** Shows the previous item in the custom list. */ private boolean moveToPreviousItem() { boolean handled = false; ... // Return true if handled successfully, otherwise return false. return handled; } }
권장사항
- 키 이벤트를
View
와Activity
에 전달하는 방법에 관해서는KeyEvent
및KeyEvent.Callback
페이지를 검토합니다. - 일관된 방향 어포던스를 유지합니다. 다음 항목으로 이동하려면 '손목을 바깥쪽으로 휙 돌리기', 이전 항목으로 이동하려면 '손목을 안쪽으로 휙 돌리기'를 사용합니다.
- 동작과 일관적인 터치를 사용합니다.
- 시각적 피드백을 제공합니다.
- 시스템의 나머지에 직관적이지 않을 수 있는 기능을 구현하기 위해 키 코드를 사용하지 않습니다. 예를 들어 작업을 취소하거나 획 돌리기로 좌우 축을 이동하는 데
KEYCODE_NAVIGATE_NEXT
를 사용하지 마세요. - 사용자 인터페이스의 일부가 아닌 요소(예: 화면을 벗어나거나 부분적으로 덮인 뷰)에서 키 이벤트를 가로채지 않습니다. 이는 모든 키 이벤트에 동일합니다.
- 반복되는 획 돌리기 동작을 자체적인 새로운 동작으로 재해석하지 않습니다. 이는 시스템의 '손목 흔들기' 동작과 충돌할 수도 있습니다.
동작 키 이벤트를 수신할 뷰에는 포커스가 있어야 합니다.
View.setFocusable()
을 참고하세요.동작은 키 이벤트로 처리되기 때문에 '터치 모드'에서 전환을 트리거하여 예기치 않은 작업으로 이어질 수 있습니다. 사용자는 터치와 동작을 번갈아 사용할 수 있으므로
View::setFocusableInTouchmode()
메서드가 필요할 수 있습니다. 경우에 따라, '터치 모드'를 오갈 때 포커스가 변경될 경우 의도한 뷰에 포커스가 오도록 하려면setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS)
를 사용해야 할 수 있습니다.- 신중하게
requestFocus()
및clearFocus()
를 사용합니다.requestFocus()
를 호출할 때 뷰에 포커스가 있는 것이 적절한지 확인합니다. 뷰가 화면을 벗어나거나 다른 뷰로 덮여 있는 경우 동작이 콜백을 트리거하면 사용자가 놀랄 수 있습니다.clearFocus()
메서드는 다른 적절한 뷰를 찾기 위해 포커스 검색을 시작합니다. 뷰 계층 구조에 따라, 검색에 상당한 계산이 필요할 수 있습니다. 또한 포커스를 받을 것으로 예상하지 않은 뷰에 포커스가 할당될 수도 있습니다.
키 이벤트는 뷰 계층 구조에서 포커스가 있는 뷰로 먼저 전달됩니다. 포커스가 놓인 뷰가 이벤트를 처리하지 않으면(즉,
false
를 반환함) 포커스를 받을 수 있고KeyListener
를 보유하고 있더라도 이벤트가 상위 뷰에 전달되지 않습니다. 오히려 포커스가 있는 뷰 계층 구조를 보유한 현재 활동으로 이벤트가 전달됩니다.따라서 상위 수준의 모든 이벤트를 포착한 다음 관련 코드를 전달해야 할 수 있습니다. 또는 활동을 서브클래스로 분류하고
dispatchKeyEvent(KeyEvent event)
메서드를 재정의하여 필요한 경우 키를 가로채거나 하위 레이어에서 처리되지 않는 키를 처리할 수도 있습니다.