컴포즈는 효율적으로 UI를 렌더링하기 위해서 재구성 작업 중 각 컴포넌트를 한 번만 측정하도록 제한합니다.
부모 컴포저블에서 재구성 과정에서 자식을 측정하기 전부터 그 크기 정보를 알아야 하는 경우 문제가 발생합니다.
예를 들어, 폭이 가장 넓은 자식과 일치하도록 Column의 폭을 조절하기 위해서는 자식의 폭을 알아야 할 수 있습니다.
부모는 자식의 크기를 측정할 수 없지만 모든 컴포저블은 콘텐츠를 편안하게 렌더링할 수 있는 내재적 최대 및 최소 크기를 갖기 때문에 내재적 측정값(intrinsic measurement)을 이용하면 ‘한 번만 측정한다’는 규칙을 어기지 않고도 크기 정보를 얻을 수 있습니다.
Modifier가 없다면 Row나 Column 같은 레이아웃 컴포저블은 자기 부모 컴포저블에서 설정한 이용할 수 있는 모든 공간을 차지하는 크기로 설정됩니다.
반면, IntrinsicSize를 이용하면, 해당 컴포저블은 그 자식들의 공간 요구(Min, Max)에 맞춰서 크기를 설정합니다. 따라서, 하나 이상의 자식들의 크기가 동적으로 변경될 때 매우 유용합니다.
부모 컴포저블은 IntrinsicSize 열거형의 Min, Max 값을 통해 그 자식의 크기 정보를 얻을 수 있습니다. IntrinsicSize는 가장 넓은(큰) 자식이 가질 수 있는 최댓값, 최솟값에 대한 정보를 부모에게 제공합니다. 부모는 이 값을 이용해서 자식이 필요로 하는 크기에 기반해서 크기에 관한 결정을 내릴 수 있습니다.
Row(modifier = Modifier.heignt(IntrinsicSize.min){
...
}
Row의 높이는 가장 큰 자식을 표시할 수 있는 최소 높이로 설정됩니다.
Column(modifier = Modifier.width(IntrinsicSize.max){
...
}
Column의 너비는 가장 넓은 폭을 가진 자식의 최대 가능 너비로 설정됩니다.
모든 컴포저블은 기기 화면에서 공간을 필요하며, 많은 컴포저블은 사용할 수 있는 공간의 변화에 적응할 수 있습니다.
Text 컴포저블로 예시를 설명하겠습니다.
한 행의 텍스트를 표시하는 Text 컴포저블의 최대 폭(Max)은 컴포저블이 표시하는 텍스트의 길이와 같습니다.
한 줄로 텍스트를 표시할 수도 있지만 여러 줄로 나타낼 수도 있습니다. 이렇게 된다면 내용을 표시하기 위해 필요한 폭이 줄어들게 됩니다. 높이 제한이 없는 경우 Text 컴포저블이 필요로한 최소 폭(Min)은 텍스트 문자열에서 가장 긴 단어의 길이와 같게 됩니다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
GeminiSampleTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
MainScreen()
}
}
}
}
}
@Composable
fun MainScreen() {
var text by remember { mutableStateOf("") }
val onTextChange = { input: String ->
text = input
}
TODO("Max OR Min IntrinsincSize")
}
@Composable
fun CustomTextField(
text: String,
onTextChange: (String) -> Unit,
modifier: Modifier = Modifier
) {
TextField(
value = text,
onValueChange = onTextChange,
modifier = modifier
)
}
MainScreen 컴포저블 함수 하위에 아래 코드와 같이 Column을 배치합니다.
Column(
Modifier
.width(200. dp)
.padding(5. dp)) {
Column(
Modifier.width(IntrinsicSize.Max)
) {
Text(
Modifier.padding(start = 4. dp),
text = text
)
Box(
modifier = Modifier
.height(10. dp)
.fillMaxWidth()
.background(Color.Black)
)
}
CustomTextField(text = text, onTextChange = onTextChange)
}
IntrinsicSize.Max
으로 설정한 결과입니다. Column의 너비가 입력되는 문자열의 길이에 따라 변경되는 것을 볼 수 있습니다.
Column(
Modifier
.width(200. dp)
.padding(5. dp)) {
Column(
Modifier.width(IntrinsicSize.Min)
) {
Text(
modifier = Modifier.padding(start = 4. dp),
text = text
)
Box(
Modifier
.height(10. dp)
.fillMaxWidth()
.background(Color.Black)
)
}
CustomTextField(text = text, onTextChange = onTextChange)
}
IntrinsicSize.Min
으로 설정한 결과입니다. Column의 너비가 입력되는 문자열의 가장 긴 문자의 길이에 맞추어서 변경되는 것을 볼 수 있습니다.