【问题标题】:Jetpack Compose - Make Image scale to the available size in Column/RowJetpack Compose - 使图像缩放到列/行中的可用大小
【发布时间】:2021-12-24 21:54:54
【问题描述】:

考虑下图:

我有一个 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 的大小?非常感谢任何帮助。

【问题讨论】:

    标签: android android-jetpack-compose android-jetpack


    【解决方案1】:

    您没有在正确的孩子上使用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}")
            }
        }
    }
    

    【讨论】:

    • weight 修饰符是对的。但这仍然不够。仅使用它不会缩放我的图像。添加fillMaxSize 会将Text 元素推到底部。添加aspectRatio 修饰符(宽度/高度)仍然是相同的结果。与此同时,我使用ConstraintLayout 使其工作。
    • @daniyelp weight 将采用所有可用高度(默认 fill 参数设置为 true)。如果您也需要缩放宽度,可以添加fillMaxWidth。 “将文本元素推到底部”是什么意思? This 是将fillMaxWidth 添加到Image 后我的代码的输出
    • 在您的输出中,图像似乎占据了顶部和底部的所有剩余空间。我希望第一个 ColumnverticalArrangement = Arrangement.SpaceEvenly 应用于 ImageText 元素。尝试显示 5 个 Text 元素而不是 20 个,您可能会明白我所说的那些被推到底部的意思。查看我的答案中的图片,了解我希望正确结果的样子。
    • @daniyelp 您可以为weight 指定fill = false,在这种情况下它不会填充可用高度。查看更新的答案
    • 图像仍然很小!无论显示多少 Text 元素。 (抱歉回复晚了)
    【解决方案2】:

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

    ...
    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
    )
    ...
    

    【讨论】:

    • 我认为有人向您发送了交换高度和宽度位置的建议。但是,aspectRatio 修饰符仍然不够。如果我添加更多 Text 元素,它们将被推出屏幕。 Image 不会缩小。与此同时,我使用ConstraintLayout 使它工作(见我的回答)。只是无法使用Column。但是您可以考虑如何在您的情况下解决它。
    【解决方案3】:

    使用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,他可以发布答案,我可以接受。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-06
      • 1970-01-01
      • 2020-06-14
      • 2021-07-13
      • 1970-01-01
      • 2016-07-30
      • 2016-04-22
      • 2016-05-24
      相关资源
      最近更新 更多