Android compose, проблема с размером индикатора с катушкой

Недавно я пытаюсь перейти на 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
            )
        }
    }
}

Затем работает хорошо, но я не знаю, почему Кто-нибудь знает, почему?

Я пытался найти, как работать с этим кодом, но не смог

2 ответа

Как упомянул @Jan Bina, это означает, что он накладывает минимальные ограничения только на своего прямого потомка. В этом ответе я объяснил , как это влияет на 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

Я ответил о типах ограничений здесь

Если вы просмотрите исходный код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.

Другие вопросы по тегам