focusGroup 수정자를 사용하여 여러 포커스 타겟을 함께 그룹화할 수 있습니다.
그룹화를 사용하면 포커스 계층 구조를 관리하고, 논리적 UI 영역 (예: 툴바, 대화상자 작업, 카드 목록)을 격리하고, 포커스가 영역에 들어가거나 영역에서 나갈 때 가로챌 수 있습니다.
표적 집단 개념: 시작, 종료, 기본 순회
포커스 그룹은 하위 포커스 타겟 주위에 일관된 탐색 경계를 설정합니다. 이 경계를 넘어 포커스가 이동하는 방식을 이해하려면 다음 두 가지 핵심 개념을 알아야 합니다.
- Enter: 포커스 그룹 외부의 요소에서 그룹 내부의 요소로 포커스가 전환될 때 발생하는 이벤트입니다.
- 종료: 포커스가 그룹의 마지막 내부 요소를 벗어나 외부 포커스 타겟으로 전환될 때 발생하는 이벤트입니다.
기본 포커스 순회 동작
기본적으로 포커스 그룹이 외부에서 포커스를 받으면 다음이 적용됩니다.
- 그룹 입력: Compose는 내부 하위 포커스 타겟을 자동으로 선택합니다. 1차원 (Tab) 탐색의 경우 시각적 모양 순서로 첫 번째 하위 요소를 선택합니다. 2차원 (화살표 키 또는 D패드) 탐색의 경우 들어오는 방향에 기하학적으로 가장 가까운 하위 요소를 선택합니다.
- 그룹 내 탐색: 탐색 키를 반복해서 누르면 그룹으로 둘러싸인 동위 포커스 타겟 간에 포커스가 이동합니다.
- 그룹 종료: 사용자가 그룹 내 마지막 포커스 타겟을 지나 이동하면 다음 키 누르기로 그룹을 종료하고 포커스를 그룹 외부의 인접한 포커스 타겟으로 이동합니다.
포커스 항목 리디렉션 맞춤설정
많은 UI 디자인에서 기본 입력 타겟 (예: 표시 순서의 첫 번째 하위 요소)은 사용자에게 가장 논리적이거나 편리한 선택이 아닙니다.
의도 및 사용 사례
왼쪽에 '취소' 버튼이 있고 오른쪽에 기본 '확인' 버튼이 있는 확인 대화상자를 생각해 보세요. 사용자가 양식 입력란에서 버튼 바로 아래로 이동하는 경우:
- 기본 동작: 시각적 표시 순서에서 첫 번째 버튼이므로 포커스가 'Cancel'에 맞춰집니다.
- 의도된 동작: 'Confirm'이 기본 권장 작업이므로 포커스 순서에서 앞부분에 있는 버튼 그룹을 입력할 때 포커스가 'Confirm'에 직접 도달하도록 할 수 있습니다. 이때 사용자는 필요한 경우 Left를 눌러 'Cancel'을 선택할 수 있습니다.
다른 일반적인 사용 사례는 다음과 같습니다.
TabRow를 입력할 때 현재 선택된 탭으로 포커스를 직접 이동합니다.- 미디어 재생 바에 들어갈 때 포커스를 '재생 / 일시중지' 컨트롤로 직접 이동합니다.
onEnter 및 FocusRequester를 사용한 구현
표적 집단에 진입할 때 포커스를 리디렉션하려면 다음 단계를 따르세요.
- 관련 포커스 타겟을 포함하는 상위 컨테이너에
focusGroup수정자를 적용합니다. focusProperties수정자를 컨테이너에 적용하고onEnter콜백을 구성합니다.onEnter콜백 (FocusEnterExitScope로 범위 지정됨)에서focusRequester를 사용하여 기본 하위 요소와 연결된FocusRequester에서requestFocus()를 호출합니다.
val defaultChildRequester = remember { FocusRequester() } Row( modifier = Modifier .focusGroup() .focusProperties { // Intercept entry into this group and redirect focus to the primary action onEnter = { defaultChildRequester.requestFocus() } } ) { Button(onClick = { /* Cancel action */ }) { Text("Cancel") } Button( onClick = { /* Confirm action */ }, modifier = Modifier.focusRequester(defaultChildRequester) ) { Text("Confirm (Default)") } }
onEnter 및 onExit 내에서 cancelFocusChange()를 호출하여 경계 전반의 포커스 전환을 완전히 차단하거나 requestedFocusDirection를 검사하여 사용자가 Tab, Down 또는 Left를 사용하여 탐색했는지에 따라 라우팅을 맞춤설정할 수도 있습니다.
스크롤 가능한 컨테이너는 기본적으로 포커스 그룹입니다.
Jetpack Compose에서 LazyRow, LazyColumn, LazyVerticalGrid와 같은 스크롤 가능한 컨테이너는 자동으로 포커스 그룹 역할을 합니다.
onEnter 또는 onExit 콜백을 설정하기 위해 focusGroup 수정자를 명시적으로 적용할 필요는 없습니다.
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 포커스 타겟
- 포커스 순회 순서
- 텍스트 입력란에 포커스
- 포커스 복원
- 프로그래매틱 방식으로 포커스 요청
- 포커스 탐색 테스트