Недавно я пытаюсь перейти на Jetpack compose.
Итак, я хочу показать «карту», где есть «индикатор» при загрузке но я не могу изменить размер "индикатора" в "SubcomposeAsyncImage"
@Composable
private fun SponsorDialogContent(
imgUrl: String,
) {
Card(
modifier = Modifier
.width(300.dp)
.wrapContentHeight(),
elevation = CardDefaults.cardElevation(0.dp),
shape = RoundedCornerShape(10.dp)
) {
Box() {
SubcomposeAsyncImage(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.heightIn(min = 200.dp),
model = imgUrl,
contentDescription = null,
loading = {
CircularProgressIndicator(modifier = Modifier.size(30.dp).align(Alignment.Center), progress = 1f)
},
alignment = Alignment.Center,
contentScale = ContentScale.FillWidth
)
CircularProgressIndicator(1f, Modifier.width(30.dp).align(Alignment.Center))
}
}
}
Так. Я попробовал код ниже
@Composable
private fun SponsorDialogContent(
imgUrl: String,
) {
Card(
modifier = Modifier
.width(300.dp)
.wrapContentHeight(),
elevation = CardDefaults.cardElevation(0.dp),
shape = RoundedCornerShape(10.dp)
) {
Box() {
SubcomposeAsyncImage(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.heightIn(min = 200.dp),
model = imgUrl,
contentDescription = null,
loading = {
Box(contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
},
alignment = Alignment.Center,
contentScale = ContentScale.FillWidth
)
}
}
}
Затем работает хорошо, но я не знаю, почему Кто-нибудь знает, почему?
Я пытался найти, как работать с этим кодом, но не смог
Если вы просмотрите исходный код SubcomposeAsyncImage, вы дойдете до того места, где увидите это:
BoxWithConstraints(
modifier = modifier, // this is the modifier you passed to SubcomposeAsyncImage
contentAlignment = alignment,
propagateMinConstraints = true,
) {
// image or your loading content based on state
}
Таким образом, поведение, которое вы описываете, связано с вашим модификатором, который имеет heightIn(min = 200.dp), и вашим индикатором прогресса, который в конечном итоге становится прямым потомком этого Box, который имеет propagateMinConstraints = true.
Как упомянул @Jan Bina, у него есть propagateMinConstraints = true, что означает, что он накладывает минимальные ограничения только на своего прямого потомка. Я объяснил в этом ответе, как это влияет на Surface, потому что Surface — это коробка с propagateMinConstraints = true. Вы можете попробовать это с Box, и вы увидите те же результаты.
Surface(
modifier = Modifier.size(200.dp),
onClick = {}) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Red, RoundedCornerShape(6.dp))
) {}
}
Spacer(modifier = Modifier.height(20.dp))
Surface(
modifier = Modifier.size(200.dp),
onClick = {}) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Red, RoundedCornerShape(6.dp))
) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Green, RoundedCornerShape(6.dp))
) {}
}
}
Spacer(modifier = Modifier.height(20.dp))
Box(
modifier = Modifier.size(200.dp)
) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Red, RoundedCornerShape(6.dp))
) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Green, RoundedCornerShape(6.dp))
) {}
}
}
В первом примере на Surface Force Column имеет размер 200.dp, даже если он имеет Modifier.size(50.dp).
Во втором примере Box внутри Column имеет размер 50.dp, потому что он не является прямым потомком Surface.
В третьем примере, если мы заменим Surface (Box с propagateMinConstraints true) на Box, это позволит прямому потомку использовать свои собственные ограничения или размеры.
И когда вы устанавливаете Modifier.fillMaxWidth, вы устанавливаете ограничения как minWidth = родительская ширина, maxWidth = parentWidth
Я ответил о типах ограничений здесь