IntrinsicSize

Последнее обновление: 08.04.2024

Один из способов, с помощью которого Compose может быстро и эффективно отображать пользовательский интерфейс, заключается в ограничении измерения каждого компонента только один раз во время операции рекомпозиции. Однако иногда возникают ситуации, когда родительскому контейнеру необходимо знать информацию о размерах своих дочерних элементов, прежде чем они будут измерены в рамках рекомпозиции. Например, может потребоваться, чтобы ширина столбца соответствовала ширине его самого широкого дочернего элемента. Хотя родительский контейнер не может измерить свои вложенные компоненты, информацию о размерах можно получить, не нарушая правила "измерить один раз", используя intrinsic-измерения.

Родительский контейнер может получить информацию о размерах своих дочерних элементов, обратившись к значениям Max и Min перечисления IntrinsicSize. Это перечисление предоставляет родительскому контейнеру информацию о максимально или минимально возможной ширине или высоте его самого широкого или самого высокого дочернего элемента. Это позволяет контейнеру принимать решения о размерах, исходя из потребностей своих вложенных компонентах в размерах.

Например, установка высоту строки в зависимости от размеров вложенных компонентов:

Row(modifier = modifier.height(IntrinsicSize.Min)) {
............................ 
}

В итоге когда происходит рендеринг данной строки, ее высота будет установлена на минимально возможную высоту, которая необходима для отображения ее самого высокого дочернего элемента. налогично, следующий код настраивает ширину столбца на максимально возможную ширину его самого широкого дочернего элемента:

Column(modifier = modifier.width(IntrinsicSize.Max)) {
............................ 
}

Таким образом, используя IntrinsicSize контейнеры устанавливают свой размер в соответствии с требованиями к пространству их дочерних элементов, что особенно может быть полезно, когда один или несколько дочерних элементов подвергаются динамическим изменениям размера.

Посмотрим на примере. Пусть у нас есть следующий простейший интерфейс:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            Column(Modifier.padding(5.dp)) {
                Text("Hello METANIT.COM", Modifier.padding(start = 4.dp), fontSize = 28.sp)
                Box(Modifier.height(10.dp).fillMaxWidth().background(Color.Blue))
            }
        }
    }
}

Здесь в столбце Column расположены два компонента: Text и Box. При этом компонент Box растянут по всей ширине столбца, чтобы создать некоторую полоску под текстом:

IntrinsicSize в Jetpack Compose и Kotlin на Android

Но проблема здесь в том, что Box под текстом по ширине не соответствует тексту, так как столбец растягивается по всей ширине экрана. Мы могли бы установить для столбца точную ширину, подогнав ее под длину текста, но в этом случае при динамическом изменении текста у нас опять же были бы проблемы с размерами. И поэтому теперь применим IntrinsicSize.Max:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            Column(Modifier.padding(5.dp).width(IntrinsicSize.Max)) {
                Text("Hello METANIT.COM", Modifier.padding(start = 4.dp), fontSize = 28.sp)
                Box(Modifier.height(10.dp).fillMaxWidth().background(Color.Blue))
            }
        }
    }
}

Теперь благодаря установке для ширины столбца значения IntrinsicSize.Max этот столбец занимает ровно ту ширину, которая необходима для его содержимого:

IntrinsicSize.Max в Jetpack Compose и Kotlin на Android

Однако компонент Text также может отображать многострочный текст. Это означает, что один и тот же текст потенциально может быть размещен в нескольких строках, что значительно уменьшит ширину, необходимую для отображения этого текста. Минимальная ширина (если нет других ограничений по высоте) компонента Text может соответствовать длине его самого длинного слова. Это значение соответствует значению IntrinsicSize.Min:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.ui.unit.sp
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent{
            Column(Modifier.padding(5.dp).width(IntrinsicSize.Min)) {
                Text("Hello METANIT.COM", Modifier.padding(start = 4.dp), fontSize = 28.sp)
                Box(Modifier.height(10.dp).fillMaxWidth().background(Color.Blue))
            }
        }
    }
}
IntrinsicSize.Min в Jetpack Compose и Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850