컴포지션은 앱의 UI를 설명하며 다음을 실행하여 생성됩니다. 구성 가능한 함수입니다. 컴포지션은 UI를 설명하는 컴포저블을 살펴보겠습니다.
컴포지션 옆에는 시맨틱스라는 병렬 트리가 있습니다. 트리입니다. 이 트리는 다음과 같은 대체 방식으로 UI를 설명합니다. 접근성 서비스 및 테스트에서 쉽게 이해할 수 있음 프레임워크입니다 접근성 서비스는 트리를 사용하여 확인할 수 있습니다 테스트 프레임워크는 트리를 사용하여 앱과 상호작용합니다. 어설션을 만듭니다 시맨틱 트리는 컴포저블을 그리는 방법에 관한 정보가 포함되어 있지만, 여기에는 컴포저블의 시맨틱 의미
<ph type="x-smartling-placeholder">![일반적인 UI 계층 구조 및 시맨틱 트리](https://developer.android.com/static/develop/ui/compose/images/semantics-ui-tree.png?authuser=0000&hl=ko)
앱이 Compose 기초 및 Material 라이브러리의 컴포저블과 수정자로 구성되어 있다면 시맨틱 트리가 자동으로 채워지고 생성됩니다. 하지만 맞춤 하위 수준 컴포저블을 추가할 때는 시맨틱스를 수동으로 제공해야 합니다. 트리가 화면에 있는 요소의 의미를 올바르게 또는 완전히 나타내지 못하는 경우도 있을 수 있으며 이 경우 트리를 조정할 수 있습니다.
예를 들어 다음 맞춤 캘린더 컴포저블을 생각해보세요.
<ph type="x-smartling-placeholder">![선택 가능한 날짜 요소가 있는 맞춤 캘린더 컴포저블](https://developer.android.com/static/develop/ui/compose/images/semantics-calendar.png?authuser=0000&hl=ko)
이 예에서 전체 캘린더는 Layout
컴포저블을 사용하고 Canvas
에 직접 그리는 단일 하위 수준 컴포저블로 구현됩니다.
아무 조치를 취하지 않으면 접근성 서비스에서 충분한 수신이 되지 않습니다.
컴포저블의 콘텐츠 및
있습니다. 예를 들어 사용자가 17이 포함된 날짜를 클릭하면 접근성 프레임워크는 전체 캘린더 컨트롤에 관한 설명 정보만 수신합니다. 이 경우 TalkBack 접근성 서비스는
'캘린더'라고 알려 줘 또는 '4월 캘린더'라고 적혀 있습니다. 사용자는
어떤 날이 선택되었는지 궁금할 것입니다. 이 컴포저블을 더 많이 만들기 위해
사용할 수 있게 되면 의미론적 정보를 수동으로 추가해야 합니다
시맨틱 속성
시맨틱 의미가 있는 UI 트리의 모든 노드에는 시맨틱 트리에 병렬 노드가 있습니다. 시맨틱 트리의 노드에는 상응하는 컴포저블의 의미를 전달하는 속성이 포함되어 있습니다. 예를 들면 Text
입니다.
컴포저블에는 시맨틱 속성 text
가 포함되어 있습니다. 이는 컴포저블의 의미이기 때문입니다.
살펴보겠습니다 Icon
에는 contentDescription
속성(
Icon
의 의미를 텍스트로 전달하는 데 사용됩니다.
Compose 기반에 기반하는 컴포저블과 수정자
이미 관련 속성을 설정했습니다. 원하는 경우
또는 semantics
및
clearAndSetSemantics
수정자. 예를 들어 맞춤
접근성 작업을 제공하고 대체 상태를 제공합니다.
설명을 표시하거나 특정 텍스트가
컴포저블을 제목으로 간주해야 합니다.
시맨틱 트리를 시각화하려면 Layout Inspector 도구를 사용하거나
테스트 내에서 printToLog()
메서드를 호출합니다. 그러면 현재
Logcat 내의 시맨틱 트리
class MyComposeTest { @get:Rule val composeTestRule = createComposeRule() @Test fun MyTest() { // Start the app composeTestRule.setContent { MyTheme { Text("Hello world!") } } // Log the full semantics tree composeTestRule.onRoot().printToLog("MY TAG") } }
이 테스트는 다음과 같이 출력됩니다.
Printing with useUnmergedTree = 'false'
Node #1 at (l=0.0, t=63.0, r=221.0, b=120.0)px
|-Node #2 at (l=0.0, t=63.0, r=221.0, b=120.0)px
Text = '[Hello world!]'
Actions = [GetTextLayoutResult]
시맨틱 속성이 컴포저블의 의미를 전달하는 방식을 고려해 보세요. 예를 들어
Switch
사용자에게는 다음과 같이 표시됩니다.
![](https://developer.android.com/static/develop/ui/compose/images/semantics-switches.png?authuser=0000&hl=ko)
이 요소의 의미를 설명하려면 다음과 같이 말하세요. "이 'On'의 전환 가능한 요소인 스위치입니다. 있습니다. 이 버튼을 상호작용하도록 했습니다."
이것이 시맨틱 속성이 사용되는 정확한 용도입니다. 시맨틱 노드 이 Switch 요소의 클래스에는 Layout Inspector:
![Switch 컴포저블의 시맨틱 속성을 보여주는 Layout Inspector](https://developer.android.com/static/develop/ui/compose/images/semantics-layout-inspector-switch.png?authuser=0000&hl=ko)
Role
는 요소의 유형을 나타냅니다. StateDescription
에서 설명하는 방식은 다음과 같습니다.
'사용' 상태를 참조해야 합니다. 기본적으로
더 구체적으로 (예: '사용 설정됨') 상황에 따라
살펴봤습니다 ToggleableState
는 스위치의 현재 상태입니다. 이
OnClick
속성은 이 요소와 상호작용하는 데 사용되는 메서드를 참조합니다. 대상
시맨틱 속성의 전체 목록은 SemanticsProperties
객체를 지정합니다. 가능한 접근성 작업의 전체 목록은 SemanticsActions
객체를 확인하세요.
앱에서 각 컴포저블의 시맨틱 속성을 추적하면 여러 강력한 가능성이 열립니다. 예를 들면 다음과 같습니다.
- TalkBack은 속성을 사용하여 화면에 표시된 내용을 소리 내어 읽습니다. 사용자가 원활하게 상호작용할 수 있도록 합니다. Switch 컴포저블의 경우 TalkBack은 다음과 같이 말합니다. "켜짐; 전환; 두 번 탭하여 전환' 사용자는 기기의 화면을 두 번 탭하여 화면을 사용하여 스위치를 끕니다.
-
테스트 프레임워크에서는 속성을 사용하여 노드를 찾아 상호작용하고 어설션을 만듭니다. Switch의 샘플 테스트는 다음과 같을 수 있습니다.
val mySwitch = SemanticsMatcher.expectValue( SemanticsProperties.Role, Role.Switch ) composeTestRule.onNode(mySwitch) .performClick() .assertIsOff()
병합된 시맨틱 트리와 병합되지 않은 시맨틱 트리
앞서 언급했듯이 UI 트리의 각 컴포저블에는 시맨틱 속성이 0개 이상 설정되어 있을 수 있습니다. 컴포저블에 시맨틱 속성이 설정되어 있지 않으면 시맨틱 트리의 일부로 포함되지 않습니다. 따라서 시맨틱 트리에는 실제로 시맨틱 의미가 포함된 노드만 포함됩니다. 그러나 때로는 화면에 표시되는 내용의 정확한 의미를 전달하기 위해 노드의 특정 하위 트리를 병합하여 하나로 처리하는 것도 유용합니다. 이렇게 하면 각 노드를 처리하는 대신 노드 집합에 대해 전체적으로 추론할 수 있습니다. 하위 노드를 하나씩 개별적으로 조정할 수 있습니다 일반적으로 이 트리의 각 노드는 접근성 서비스를 사용할 때 포커스 가능 요소를 나타냅니다.
이러한 컴포저블의 예는 Button
입니다. 버튼을 추론할 수 있습니다.
를 단일 요소로 간주합니다.
Button(onClick = { /*TODO*/ }) { Icon( imageVector = Icons.Filled.Favorite, contentDescription = null ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("Like") }
시맨틱 트리에서는 버튼의 하위 요소의 속성이 병합됩니다. 버튼은 트리에서 단일 리프 노드로 표시됩니다.
![병합된 단일 리프 시맨틱 표현](https://developer.android.com/static/develop/ui/compose/images/semantics-merged-single-leaf.png?authuser=0000&hl=ko)
컴포저블과 수정자는 Modifier.semantics
(mergeDescendants = true) {}
를 호출하여 하위 요소의 시맨틱 속성을 병합하려고 함을 나타낼 수 있습니다. 이 속성을 true
로 설정하면 시맨틱 속성을 병합해야 함을 나타냅니다. Button
예에서 Button
는
컴포저블은 다음을 포함하는 clickable
수정자를 내부적으로 사용합니다.
semantics
수정자 따라서 버튼의 하위 노드가 병합됩니다.
접근성 도움말을 읽고 변경해야 하는 경우에 대해 자세히 알아보세요.
병합 동작을 참고하세요.
Foundation 및 Material Compose 라이브러리의 여러 수정자와 컴포저블에는 이 속성이 설정되어 있습니다. 예를 들어 clickable
과 toggleable
수정자는 자동으로 하위 요소를 병합합니다. ListItem
컴포저블도 하위 요소를 병합합니다.
트리 검사
시맨틱 트리는 사실상 서로 다른 두 개의 트리입니다. 병합된 시맨틱이 있음
트리는 mergeDescendants
가 true
로 설정되면 하위 노드를 병합합니다.
병합되지 않은 시맨틱 트리도 있습니다. 이 트리는 병합을 적용하지 않지만
모든 노드를 온전하게 유지할 수 있습니다 접근성 서비스는 병합되지 않은 트리를 사용하여
mergeDescendants
및 자체 병합 알고리즘을 기반으로
속성 테스트 프레임워크는 기본적으로 병합된 트리를 사용합니다.
printToLog()
메서드로 두 트리를 모두 검사할 수 있습니다. 기본적으로
이전 예에서 병합된 트리가 기록됩니다. 병합되지 않은 트리를 출력하는 방법
대신 onRoot()
매처의 useUnmergedTree
매개변수를 다음과 같이 설정합니다.
true
:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("MY TAG")
Layout Inspector를 사용하면 병합된 시맨틱과 병합되지 않은 시맨틱을 모두 표시할 수 있습니다. 보기 필터에서 원하는 필터를 선택해 보세요.
<ph type="x-smartling-placeholder">![병합된 시맨틱 트리와 병합되지 않은 시맨틱 트리를 모두 표시할 수 있는 Layout Inspector 뷰 옵션](https://developer.android.com/static/develop/ui/compose/images/semantics-layout-inspector-menu.png?authuser=0000&hl=ko)
트리의 각 노드의 경우 Layout Inspector에는 병합된 시맨틱과 속성 패널에서 이 노드에 설정된 시맨틱이 모두 표시됩니다.
<ph type="x-smartling-placeholder">![시맨틱 속성이 병합되고 설정됨](https://developer.android.com/static/develop/ui/compose/images/semantics-merged-and-set.png?authuser=0000&hl=ko)
기본적으로 테스트 프레임워크의 매처는 병합된 시맨틱 트리를 사용합니다.
따라서 내부에 표시된 텍스트를 일치시켜 Button
와 상호작용할 수 있습니다.
다음과 같습니다.
composeTestRule.onNodeWithText("Like").performClick()
useUnmergedTree
매개변수를 설정하여 이 동작을 재정의합니다.
onRoot
매처와 마찬가지로 true
에 대한 매처.
병합 동작
컴포저블이 하위 요소를 병합해야 한다고 나타낼 때 이 병합은 정확히 어떻게 발생하나요?
각 시맨틱 속성에는 정의된 병합 전략이 있습니다. 예를 들어
ContentDescription
속성은
목록. 다음을 확인하여 시맨틱 속성의 병합 전략을 확인합니다.
SemanticsProperties.kt
의 mergePolicy
구현 속성은
상위 또는 하위 값을 가져와서 값을 목록으로 병합하거나
병합을 허용하지 않고 대신 예외가 발생하거나
사용할 수 있습니다
자체적으로 mergeDescendants
= true
를 설정한 하위 요소는 병합에 포함되지 않는다는 점에 유의해야 합니다. 예를 살펴보겠습니다.
![이미지, 텍스트, 북마크 아이콘이 포함된 목록 항목](https://developer.android.com/static/develop/ui/compose/images/semantics-dagger.png?authuser=0000&hl=ko)
다음은 클릭 가능한 목록 항목입니다. 사용자가 행을 누르면 앱이 도움말 세부정보 페이지로 이동하고 여기서 사용자는 도움말을 읽을 수 있습니다. 목록 항목 내에는 기사를 북마크하는 버튼이 있으며, 클릭 가능한 요소가 중첩되어 있으므로, 병합된 트리를 살펴보겠습니다. 행의 나머지 콘텐츠는 병합됩니다.
<ph type="x-smartling-placeholder">![행 노드 내의 목록에 여러 텍스트가 포함된 병합된 트리. 각 텍스트 컴포저블에 관한 별도의 노드가 포함된 병합되지 않은 트리](https://developer.android.com/static/develop/ui/compose/images/semantics-merged-vs-unmerged.png?authuser=0000&hl=ko)
시맨틱 트리 조정
앞서 언급했듯이 특정 시맨틱 속성을 재정의하거나 삭제할 수 있습니다. 트리의 병합 동작을 변경합니다. 이는 특히 자체 커스텀 구성요소를 만들 수 있습니다. 올바른 값을 설정하지 않은 상태에서 속성 및 병합 동작으로 인해 앱에 액세스하지 못할 수 있고 테스트는 예상한 것과 다르게 동작할 수 있습니다 몇 가지 일반적인 사용 사례에 관해 자세히 알아보기 시맨틱 트리를 조정해야 하는 위치는 접근성 문서를 참조하세요. 테스트에 대해 자세히 알아보려면 가이드를 참조하세요.
추가 리소스
- 접근성: 필수 개념 및 모든 Android 앱 개발에 공통으로 적용되는 기법
- 액세스 가능한 앱 빌드: 주요 단계 앱의 접근성을 높이기 위해
- 앱 개선 원칙 접근성: 앱의 접근성을 높이기 위해 작업할 때 명심하세요
- 접근성 테스트: Android 접근성 관련 테스트 원칙 및 도구
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- Compose의 접근성
- Compose의 Material Design 2
- Compose 레이아웃 테스트