android Jetpack合成-使图像缩放到列/行中的可用大小

smdncfj3  于 2023-04-10  发布在  Android
关注(0)|答案(5)|浏览(134)

请考虑以下图像:

我有一个Column,它有一个Image,还有一个Column,它有一些Text元素。我试图做的是让Image均匀地扩展到可用空间。我就是不能让它工作。

Column(
    modifier = Modifier
        .fillMaxSize()
        .background(Color.Cyan)
        .padding(horizontal = 16.dp),
    verticalArrangement = Arrangement.SpaceEvenly
) {
    Image(
        modifier = Modifier.fillMaxWidth(),
        painter = painterResource(R.drawable.rocket_boy),
        contentDescription = null,
        contentScale = ContentScale.Fit
    )
    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        repeat(20) {
            Text(text = "${it}")
        }
    }
}

我尝试的一件事是将Image的大小设置为fillMaxSize,将第二个Columnweight设置为1f,但它没有做任何事情。也许我需要固定第二个Column的大小?非常感谢任何帮助。

pgccezyw

pgccezyw1#

您没有在正确的子节点上使用Modifier.weight。它应该应用于视图,您需要填充父节点的其余部分。
父元素将在测量未加权的子元素后划分剩余的垂直空间,并根据此权重进行分配。
Modifier.weight的参数为fill,默认参数为true。该默认参数的工作原理与Modifier.fillMaxHeight()相同(在Column的情况下),如果您不需要填写所有可用的高度,您可以指定false

Column(
    modifier = Modifier
        .fillMaxSize()
        .background(Color.Cyan)
        .padding(horizontal = 16.dp),
    verticalArrangement = Arrangement.SpaceEvenly,
    horizontalAlignment = Alignment.CenterHorizontally,
) {
    val painter = painterResource(R.drawable.ic_redo)
    Image(
        modifier = Modifier.weight(1f, fill = false)
            .aspectRatio(painter.intrinsicSize.width / painter.intrinsicSize.height)
            .fillMaxWidth(),
        painter = painter,
        contentDescription = null,
        contentScale = ContentScale.Fit
    )
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxWidth()
    ) {
        repeat(20) {
            Text(text = "${it}")
        }
    }
}
jslywgbw

jslywgbw2#

您的图像大小似乎小于屏幕最大宽度,因此图像的容器填充宽度,但图像仍然很小,如果您填充图像的高度,它会正确缩放,但图像容器填充列表下方的所有空间。您可以尝试设置和长宽比修改器,以防止容器填充所有可用空间:

...
val painter = painterResource(id = R.drawable.ic_dismiss_24)
Image(
  modifier = Modifier
                .aspectRatio(ratio = painter.intrinsicSize.height / 
  painter.intrinsicSize.width)
                .fillMaxWidth()
                .fillMaxHeight(),
  painter = painter,
  contentDescription = null,
  contentScale = ContentScale.Fit
)
...

gr8qqesn

gr8qqesn3#

使用Column无法使其正常工作,但我成功地使用了ConstraintLayout和Nestor对aspectRatio的帮助。

ConstraintLayout(
    modifier = Modifier.fillMaxSize()
) {
    val (button, text) = createRefs()

    val painter = painterResource(R.drawable.rocket_boy)
    Image(
        modifier = Modifier
            .aspectRatio(ratio = painter.intrinsicSize.width /
                    painter.intrinsicSize.height)
            .padding(16.dp)
            .constrainAs(text) {
                top.linkTo(parent.top)
                bottom.linkTo(button.top)
                height = Dimension.preferredWrapContent
                width = Dimension.preferredWrapContent
                start.linkTo(parent.start)
                end.linkTo(parent.end)
            },
        painter = painter,
        contentDescription = null,
        contentScale = ContentScale.Fit
    )

    Column(Modifier.constrainAs(button) {
        bottom.linkTo(parent.bottom, margin = 16.dp)
        top.linkTo(text.bottom)
        start.linkTo(parent.start)
        end.linkTo(parent.end)
        height = Dimension.wrapContent
    }) {
        repeat(5) {
            Text(text = "$it")
        }
    }
}

但是如果有人认为它仍然可以用Column而不是ConstraintLayout来完成,他可以发布答案,我可能会接受它。

qzwqbdag

qzwqbdag4#

如果我们考虑父Column的高度-作为Image和嵌套Column的高度之和-可以认为Image的高度应该等于从父Column的高度减去嵌套Column的高度后的高度的余数。

var textInColumnSize by remember { mutableStateOf(Size.Zero) }
var globalColumnSize by remember { mutableStateOf(Size.Zero) }
val imageHeight: Dp =
    LocalDensity.current.run { (globalColumnSize.height - 
    textInColumnSize.height).toDp() }

Column(
    modifier = Modifier
        .fillMaxSize()
        .onGloballyPositioned { coordinates ->
            globalColumnSize = coordinates.size.toSize()
        }
        .background(Color.Cyan)
        .padding(horizontal = 16.dp),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.SpaceEvenly
) {

    Image(
        modifier = Modifier
            .fillMaxWidth()
            .height(imageHeight),
        painter = painterResource(R.drawable.rocket_boy),
        contentDescription = null,
    )
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .onGloballyPositioned { coordinates ->
                textInColumnSize = coordinates.size.toSize()
            },
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        repeat(10) {
            Text(text = "$it")
        }
    }
}
fykwrbwg

fykwrbwg5#

这就是我的工作:

Column(
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Image(
        modifier = Modifier
            .size(350.dp), // you can set this to whatever size you want your image to be
        painter = painterResource(id = R.drawable.android_superhero1),
        contentDescription = null
    )
    Column {
        repeat(20) {
            Text(text = it.toString())
        }
    }
}

350.dp.size(350.dp)):

150.dp.size(150.dp)):

相关问题