Compose에서는 여러 수정자를 함께 체이닝하여 컴포저블의 디자인과 분위기를 변경할 수 있습니다. 이러한 수정자 체인은 너비 및 높이 경계를 정의하는 컴포저블에 전달된 제약 조건에 영향을 줄 수 있습니다.
이 페이지에서는 체이닝된 수정자가 제약 조건에 미치는 영향과 그에 따라 컴포저블의 측정 및 배치에 미치는 영향을 설명합니다.
UI 트리의 수정자
수정자가 서로에게 어떤 영향을 미치는지 이해하려면 컴포지션 단계에서 생성되는 UI 트리에 어떻게 표시되는지 시각화하는 것이 좋습니다. 자세한 내용은 구성 섹션을 참고하세요.
UI 트리에서 수정자를 레이아웃 노드의 래퍼 노드로 시각화할 수 있습니다.
컴포저블에 둘 이상의 수정자를 추가하면 수정자 체인이 생성됩니다. 여러 수정자를 체이닝하면 각 수정자 노드는 나머지 체인과 내부 레이아웃 노드를 래핑합니다. 예를 들어 clip
수정자와 size
수정자를 연결하면 clip
수정자 노드가 size
수정자 노드를 래핑하고 size
수정자 노드는 Image
레이아웃 노드를 래핑합니다.
레이아웃 단계에서 트리를 탐색하는 알고리즘은 동일하게 유지되지만 각 수정자 노드도 방문됩니다. 이렇게 하면 수정자가 래핑하는 수정자 또는 레이아웃 노드의 크기 요구사항과 배치를 변경할 수 있습니다.
그림 2와 같이 Image
및 Text
컴포저블의 구현 자체는 단일 레이아웃 노드를 래핑하는 수정자 체인으로 구성됩니다. Row
및 Column
구현은 하위 요소를 배치하는 방법을 설명하는 레이아웃 노드일 뿐입니다.
요약:
- 수정자는 단일 수정자 또는 레이아웃 노드를 래핑합니다.
- 레이아웃 노드는 여러 하위 노드를 배치할 수 있습니다.
다음 섹션에서는 이 멘탈 모델을 사용하여 수정자 체이닝을 추론하고 컴포저블 크기에 미치는 영향을 설명합니다.
레이아웃 단계의 제약조건
레이아웃 단계는 3단계 알고리즘에 따라 각 레이아웃 노드의 너비, 높이, x, y 좌표를 찾습니다.
- 하위 요소 측정: 노드가 하위 요소(있는 경우)를 측정합니다.
- 자체 크기 결정: 이러한 측정값을 기반으로 노드는 자체 크기를 결정합니다.
- 하위 요소 배치: 각 하위 노드는 노드의 자체 위치를 기준으로 배치됩니다.
Constraints
는 알고리즘의 처음 두 단계에서 노드의 적절한 크기를 찾는 데 도움이 됩니다. 제약조건은 노드의 너비와 높이의 최소 및 최대 경계를 정의합니다. 노드가 크기를 결정할 때 측정된 크기는 이 크기 범위 내에 있어야 합니다.
제약조건 유형
제약조건은 다음 중 하나일 수 있습니다.
- Bounded: 노드에 최대 및 최소 너비와 높이가 있습니다.
- 제한되지 않음: 노드가 크기로 제한되지 않습니다. 최대 너비 및 높이 경계는 무한대로 설정됩니다.
- 일치: 노드에 정확한 크기 요구사항을 따르라는 메시지가 표시됩니다. 최솟값과 최댓값 경계는 동일한 값으로 설정됩니다.
- 조합: 노드가 위의 제약 조건 유형 조합을 따릅니다. 예를 들어 제약 조건은 제한되지 않은 최대 높이를 허용하면서 너비를 제한하거나 정확한 너비를 설정하되 제한된 높이를 제공할 수 있습니다.
다음 섹션에서는 이러한 제약 조건이 상위 요소에서 하위 요소로 전달되는 방법을 설명합니다.
제약 조건이 상위 요소에서 하위 요소로 전달되는 방식
레이아웃 단계의 제약조건에 설명된 알고리즘의 첫 번째 단계에서 제약조건은 UI 트리의 상위 요소에서 하위 요소로 전달됩니다.
상위 노드가 하위 요소를 측정할 때 각 하위 요소에 이러한 제약 조건을 제공하여 허용되는 크기를 알려줍니다. 그런 다음 자체 크기를 결정할 때 자체 상위 요소에서 전달된 제약 조건도 준수합니다.
대략적으로 알고리즘은 다음과 같이 작동합니다.
- 실제로 차지하려는 크기를 결정하기 위해 UI 트리의 루트 노드는 하위 요소를 측정하고 동일한 제약 조건을 첫 번째 하위 요소에 전달합니다.
- 하위 요소가 측정에 영향을 미치지 않는 수정자인 경우 다음 수정자에게 제약 조건을 전달합니다. 측정에 영향을 미치는 수정자에 도달하지 않는 한 제약 조건은 수정자 체인을 통해 있는 그대로 전달됩니다. 그러면 제약 조건의 크기가 적절하게 조정됩니다.
- 하위 요소가 없는 노드('리프 노드'라고 함)에 도달하면 전달된 제약 조건에 따라 크기를 결정하고 이 확인된 크기를 상위 요소에 반환합니다.
- 상위 요소는 이 하위 요소의 측정치를 기반으로 제약 조건을 조정하고 조정된 제약 조건으로 다음 하위 요소를 호출합니다.
- 상위 요소의 모든 하위 요소가 측정되면 상위 노드는 자체 크기를 결정하고 이를 자체 상위 요소에 전달합니다.
- 이렇게 하면 전체 트리가 깊이 우선으로 탐색됩니다. 결국 모든 노드의 크기가 결정되고 측정 단계가 완료됩니다.
자세한 예는 제약 조건 및 수정자 순서 동영상을 참고하세요.
제약 조건에 영향을 미치는 수정자
이전 섹션에서는 일부 수정자가 제약 조건 크기에 영향을 줄 수 있다는 것을 알아봤습니다. 다음 섹션에서는 제약 조건에 영향을 미치는 특정 수정자를 설명합니다.
size
수정자
size
수정자는 콘텐츠의 기본 크기를 선언합니다.
예를 들어 다음 UI 트리는 200dp
로 300dp
의 컨테이너에서 렌더링되어야 합니다. 제약조건은 너비가 100dp
~300dp
이고 높이가 100dp
~200dp
이 되도록 제한됩니다.
size
수정자는 전달된 값과 일치하도록 수신되는 제약 조건을 조정합니다.
이 예시에서 값은 150dp
입니다.
너비와 높이가 가장 작은 제약 조건 경계보다 작거나 가장 큰 제약 조건 경계보다 큰 경우 수정자는 전달된 제약 조건을 준수하면서 전달된 제약 조건과 최대한 근접하게 일치시킵니다.
여러 개의 size
수정자를 체이닝하면 작동하지 않습니다. 첫 번째 size
수정자는 최솟값과 최댓값 제약 조건을 모두 고정 값으로 설정합니다. 두 번째 크기 수정자가 더 작은 크기 또는 더 큰 크기를 요청하더라도 전달된 정확한 경계를 준수해야 하므로 이러한 값을 재정의하지 않습니다.
requiredSize
수정자
노드에서 수신되는 제약조건을 재정의해야 할 경우 size
대신 requiredSize
수정자를 사용합니다. requiredSize
수정자는 수신되는 제약 조건을 대체하고 개발자가 지정한 크기를 정확한 경계로 전달합니다.
크기가 트리 위로 다시 전달되면 하위 노드가 가용 공간의 중앙에 배치됩니다.
width
및 height
수정자
size
수정자는 제약 조건의 너비와 높이를 모두 조정합니다. width
수정자를 사용하면 너비를 고정으로 설정하고 높이는 결정하지 않을 수 있습니다.
마찬가지로 height
수정자를 사용하면 고정된 높이를 설정하고 너비는 결정하지 않을 수 있습니다.
sizeIn
수정자
sizeIn
수정자를 사용하면 너비와 높이에 대한 정확한 최소 및 최대 제약 조건을 설정할 수 있습니다. 제약 조건을 세부적으로 제어해야 하는 경우 sizeIn
수정자를 사용하세요.
예
이 섹션에서는 체이닝된 수정자를 사용하는 여러 코드 스니펫의 출력을 표시하고 설명합니다.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
이 스니펫은 다음과 같은 출력을 생성합니다.
fillMaxSize
수정자는 최소 너비와 높이를 모두 최대 값(너비300dp
, 높이200dp
)으로 설정하도록 제약 조건을 변경합니다.size
수정자는50dp
크기를 사용하고 싶지만 수신되는 최소 제약 조건을 준수해야 합니다. 따라서size
수정자는200
로300
의 정확한 제약 조건 경계도 출력하므로size
수정자에 제공된 값을 사실상 무시합니다.Image
는 이러한 경계를 따르고300
x200
크기를 보고하며, 이는 트리 전체로 전달됩니다.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
이 스니펫은 다음과 같은 출력을 생성합니다.
fillMaxSize
수정자는 최소 너비와 높이를 모두 최대값(너비의 경우300dp
, 높이의 경우200dp
)으로 설정하도록 제약 조건을 조정합니다.wrapContentSize
수정자는 최소 제약 조건을 재설정합니다. 따라서fillMaxSize
는 고정된 제약 조건을 초래했지만wrapContentSize
는 제한된 제약 조건으로 다시 재설정합니다. 이제 다음 노드는 전체 공간을 다시 차지하거나 전체 공간보다 작을 수 있습니다.size
수정자는 제약 조건을50
의 최소 및 최대 경계로 설정합니다.Image
는50
x50
크기로 확인되고size
수정자는 이를 전달합니다.wrapContentSize
수정자에는 특수 속성이 있습니다. 자식을 가져와 전달된 사용 가능한 최소 경계의 중앙에 배치합니다. 따라서 상위 요소와 통신하는 크기는 전달된 최소 경계와 같습니다.
세 가지 수정자만 조합하면 컴포저블의 크기를 정의하고 상위 요소에서 가운데로 배치할 수 있습니다.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
이 스니펫은 다음과 같은 출력을 생성합니다.
clip
수정자는 제약 조건을 변경하지 않습니다.padding
수정자는 최대 제약 조건을 낮춥니다.size
수정자는 모든 제약 조건을100dp
로 설정합니다.Image
는 이러한 제약 조건을 준수하며100dp
x100
크기를 보고합니다.padding
수정자는 모든 크기에10dp
를 추가하므로 보고된 너비와 높이가20dp
만큼 증가합니다.- 이제 그리기 단계에서
clip
수정자는120dp
를 통해120
의 캔버스에 작동합니다. 따라서 해당 크기의 원 마스크가 생성됩니다. - 그런 다음
padding
수정자는 모든 크기에서 콘텐츠를10dp
만큼 안쪽으로 넣으므로 캔버스 크기가100dp
만큼100
로 줄어듭니다. Image
가 캔버스에 그려집니다. 이미지는120dp
의 원래 원을 기준으로 잘리므로 출력은 원형이 아닌 결과입니다.