Android Jetpack Compose IconButton 内边距

31
如何移除 IconButton 中的填充?我希望列中的项目具有相同的起始填充{{start padding}}。

preview image

Column(
    modifier = Modifier
        .fillMaxWidth() 
        .padding(horizontal = 16.dp)
) {
    IconButton(onClick = { }) {
        Icon(asset = Icons.Filled.Search)
    }
    Text("Some text")
} 
3个回答

54

这个空间是由于可访问性触摸目标和默认大小48.dp造成的。

1.2.0开始,改变默认行为并删除额外空间的最佳方法是禁用LocalMinimumInteractiveComponentEnforcement并应用size修饰符:

CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
    IconButton(
        modifier = Modifier.size(24.dp),
        onClick = { }
    ) {
        Icon(
            Icons.Filled.Search,
            "contentDescription",
        )
    }
}

请注意,如果组件靠近布局的边缘/靠近另一个没有填充的组件,可能会没有足够的空间来实现可访问的触摸目标。

1.0.0 版本中,IconButton 使用内部修饰符应用默认大小:IconButtonSizeModifier = Modifier.size(48.dp)

您可以使用类似以下的方式进行修改:

IconButton(modifier = Modifier.
        then(Modifier.size(24.dp)),
    onClick = { }) {
    Icon(
        Icons.Filled.Search,
        "contentDescription",
        tint = Color.White)
}

在编程中,使用.then 来正确按顺序应用size十分重要。

enter image description here


1
如果我想让触摸目标的宽度和高度自适应内容怎么办?我尝试了Modifier.then(Modifier.wrapContentSize()),但没有起作用。 - Charles Woodson
你好,能否确认 then 是否仍然需要?根据源代码Modifier.then(x) 等同于 x。而且似乎没有 this 也能正常工作,我有遗漏什么吗? - Phil Dukhov
@PhilDukhov 感谢您的反馈,非常感激。我已经更新了答案。之前IconButton 的大小被硬编码为 48.dp 并带有一个 then 修饰符,这里使用 1.0.0 版本的原因是什么。现在最好的解决方案已经不同了。 - Gabriele Mariotti

10
IconButton包装在CompositionLocalProvider中,以覆盖LocalMinimumTouchTargetEnforcement的值,该值强制实施48.dp的最小触摸目标。
CompositionLocalProvider(
    LocalMinimumTouchTargetEnforcement provides false,
) {
    IconButton(onClick = { }) {
        Icon(
            imageVector = Icons.Filled.Search,
            contentDescription = "Search",
        )
    }
}

2
如果您只是用 IconButton 处理点击事件,而不是:
IconButton(onClick = { // Todo -> handle click }) {
    Icon(asset = Icons.Filled.Search)
}

您可以使用:

Icon(
    asset = Icons.Filled.Search,
    modifier = Modifier.clickable { // Todo -> handle click },
)

通过这种方式,您无需去除额外的填充。


1
不错的选择,但在这种情况下你无法获得点击涟漪效果。 - gtxtreme
@gtxtreme,你可以实际上有两种方法:要么将LocalIndication的默认行为更改为rememberRipple(),要么在你的clickable修饰符中传递indication = rememberRipple(bounded = true) - Saman Sattari

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