Реагирующий размер Jetpack Compose в ConstraintLayout — Dimension.fillToConstraints перезаписывает модификаторы .sizeIn, .widthIn, .heightIn
Я пытаюсь иметь компонуемую шкалу внутриConstrainLayout
пока не будет достигнут указанный максимальный размер (обычно путем установки или модификатора) или не будут достигнуты границы ограничений.
Использование only или приведет к отображению компонуемого всегда в минимальном размере.
Итак, мы указываем.fillMaxSize
на компонуемый, чтобы занимать максимальное количество места (до указанного maxSize). Все идет нормально..
Но теперь, когда ConstraintLayout становится меньше, например, из-за меньшего экрана и, следовательно, границы компонуемого превышают ограничения, компонуемый не уменьшается.
Это кажется понятным, потому что мы не указали, что размер компонуемого должен ориентироваться на границы указанных ограничений. Поэтому мы указываем и используем только пространство, вытекающее из заданных ограничений.
И тут возникает проблема.height = Dimensions.fillToConstraints
иwidth = Dimensions.fillToConstraints
кажется, перезаписывают.sizeIn
,.widthIn
или.heightIn
Модификатор, потому что теперь размер компонуемого всегда настолько велик, насколько он может быть внутри заданных ограничений, не обращая внимания наmaxWidth
илиmaxHeight
указано ранее.
Обходной путь — поместить этот компонуемый объект в другой, например, в блок, и настроить модификатор следующим образом:
ConstraintLayout {
...
Box(
modifier = Modifier.constrainAs(icon) {
top.linkTo(greeting.bottom) // some composable on top
bottom.linkTo(menuButtons.top) // some composable on bottom
start.linkTo(parent.start)
end.linkTop(parent.end)
height = Dimension.fillToConstraints
width = Dimension.fillToConstraints
}
) {
Icon( // the size responsive composable
imageVector = Icons.Outlined.RequestQuote,
contentDescription = null,
modifier = Modifier
.sizeIn(20.dp, 20.dp, 200.dp, 200.dp) // min and max size
.fillMaxSize()
.align(Alignment.Center)
)
}
...
}
Это дало бы нам желаемое поведение. Но, на мой взгляд, дополнительно указанное поле представляет собой ненужные накладные расходы. Итак, мой вопрос:
Есть ли способ получить это поведение без использования вторичного компонуемого только с использованием определенной конфигурации модификатора?
2 ответа
Основываясь на ответе @hoford, который подал мне идею использования.atMost()
и.atLeast()
модификаторы, которые я придумал:
ConstraintLayout {
...
Icon(
imageVector = Icons.Outlined.RequestQuote,
contentDescription = null,
modifier = Modifier.constrainAs(icon) {
top.linkTo(greeting.bottom) // some composable on top
bottom.linkTo(menuButtons.top) // some composable on bottom
start.linkTo(parent.start)
end.linkTop(parent.end)
height = Dimension.fillToConstraints.atMost(200.dp).atLeast(20.dp)
width = Dimension.fillToConstraints.atMost(200.dp).atLeast(20.dp)
}
)
Это можно сделать непосредственно в ограничениях ограничения. Я думаю, что вы ищете что-то вроде
ConstraintLayout {
...
Icon(
imageVector = Icons.Outlined.RequestQuote,
contentDescription = null,
modifier = Modifier.constrainAs(icon) {
top.linkTo(greeting.bottom) // some composable on top
bottom.linkTo(menuButtons.top) // some composable on bottom
start.linkTo(parent.start)
end.linkTop(parent.end)
height = Dimension.preferredWrapContent.atMost(200.dp).atLeast(20.dp)
width = Dimension.preferredWrapContent.atMost(200.dp).atLeast(20.dp)
}
)