如何在Jetpack Compose中减小图标大小以匹配行高

11
我有以下可组合的东西。
@Composable
fun Temp() {
    Row(
        modifier = Modifier
            .background(Color.Red)
            .height(IntrinsicSize.Min)
            .fillMaxWidth()
    ) {
        Text(text = "Hello", fontSize = 10.sp)
        Icon(
            imageVector = Icons.Default.Star,
            contentDescription = "Star",
            modifier = Modifier.fillMaxHeight()
        )
    }
}

图标高度不会减少到24.dp以下。有没有办法达到这个效果?我希望图标的大小只是父行的高度。 如果文本很大,图标的大小就会增加。我认为最小图标大小为24.dp是原因所在。如何使图标变小?

我不知道怎么做,但是我看了代码。如果传递了imageVector,则图标使用DefaultIconSizeModifier = Modifier.size(24.dp)。否则使用painter的大小。因此,请尝试添加所需大小的矢量资源,然后像这样使用:Icon(painter = painterResource(R.drawable.ic_baseline_star_10) - vitidev
2个回答

13

你的代码实际上按预期运行 - 这是内在计算的工作方式。

Compose检查每个视图的最小高度并选择这些值中的最大值。在你的情况下,图片的最小高度与图片的内在大小有关,而在Icons.Default情况下你无法控制它。

一种可能的解决方案是使用Modifier.layout。当Compose计算内在高度时,高度约束将是无限的,在这种情况下,你可以将其布局为零大小视图,以便你的文本会更高。当确定内在高度时,你可以测量和定位图标:

Row(
    modifier = Modifier
        .background(Color.Red)
        .height(IntrinsicSize.Min)
        .fillMaxWidth()
) {
    Text(text = "Hello", fontSize = 10.sp)
    Icon(
        imageVector = Icons.Default.Star,
        contentDescription = null,
        modifier = Modifier
            .layout { measurable, constraints ->
                if (constraints.maxHeight == Constraints.Infinity) {
                    layout(0, 0) {}
                } else {
                    val placeable = measurable.measure(constraints)
                    layout(placeable.width, placeable.height) {
                        placeable.place(0, 0)
                    }
                }
            }
    )
}

通过使用 Modifier.layout,您可以改变视图的大小和位置。通常您会像这样使用它:

  1. 第一个参数 measurable 是一个对象,您可以在其上使用 constraints - 第二个 layout 参数,调用 measure 方法。 measure 会计算视图所占据的大小,并考虑 constraints
  2. layout 中,您需要传递所需的视图大小 - 通常可以从前面一步得到 placeable
  3. layout 内部,您需要在 placeable 上调用 place 并传递所需的偏移量。

使用 height(IntrinsicSize.Min) layout 时,内容会被多次调用:

  1. 在第一次或前几次调用中,最大高度约束等于 Infinity,因此内在计算可以选择正确的大小并忽略父级大小。
  2. 在最后一次调用中,最大高度约束等于计算得出的父级内在高度。

在我的代码中,在进行首次调用并且高度约束等于 Infinity 时,我会说此视图的大小为零,因此不会计入内在度量中。当内在高度被定义时,我可以使用最终的约束对其进行布局。


2
这个有效了,谢谢。你能否解释一下我们到底在做什么? - Diken Mhrz
3
@DikenMhrz 我添加了更详细的解释。 - Phil Dukhov
1
我一直在查看许多Stack Overflow的帖子,但最终这个问题和答案正是我所需要的。感谢Diken发布问题,也感谢@PhilDukhov提供了出色的答案和详尽的解释! - Clark Sandholtz

0

我采用了@Phil的答案,并将其转化为一个扩展,可以被重复使用。

fun Modifier.matchRowSize() : Modifier {
    return layout { measurable, constraints ->
        if (constraints.maxHeight == Constraints.Infinity) {
            layout(0, 0) {}
        } else {
            val placeable = measurable.measure(constraints)
            layout(placeable.width, placeable.height) {
                placeable.place(0, 0)
            }
        }
    }
}

可以在您的图标中使用:

Row(
    modifier = Modifier
        .height(IntrinsicSize.Min)
        .padding(8.dp)
) {
    Icon(
        imageVector = Icons.Default.Star,
        contentDescription = null,
        modifier = Modifier
            .matchRowSize() // <-- here
    )
    Spacer(modifier = Modifier.size(10.dp))
    Text(text = "Hello", fontSize = 17.sp)
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接