如何在 Jetpack Compose 中添加保证金?

Posted

技术标签:

【中文标题】如何在 Jetpack Compose 中添加保证金?【英文标题】:How to add Margin in Jetpack Compose? 【发布时间】:2020-11-06 09:42:00 【问题描述】:

究竟如何在Jetpack Compose 中添加保证金?

我可以看到有一个Modifier 用于填充Modifier.padding(...),但我似乎找不到一个用于边距的,还是我失明了?

请有人指导我。

非常感谢。

【问题讨论】:

您可以将其包装在带有填充物的容器中。是的,我知道... 我也是这么想的......在 Flutter 中它是怎么做的......我虽然在 compose 中有一些不同的东西。 【参考方案1】:

您可以将填充和边距视为同一事物(将其想象为“间距”)。填充可以在同一个可组合中应用两次(或更多),并实现与使用边距+填充相似的行为。例如:

val shape = CircleShape
Text(
    text = "Text 1",
    style = TextStyle(
        color = Color.White,
        fontWeight = FontWeight.Bold,
        textAlign = TextAlign.Center),
    modifier = Modifier.fillMaxWidth()
        .padding(16.dp)
        .border(2.dp, MaterialTheme.colors.secondary, shape)
        .background(MaterialTheme.colors.primary, shape)
        .padding(16.dp)
)

结果如下:

如你所见,第一个padding 在组件和它的边框之间添加了一个空格。然后定义背景和边框。最后,设置一个新的padding,在边框和文本之间添加空间。

【讨论】:

我与来自 UI 工具包的 Adam Powell 和 Leland Richardson 进行了长时间的讨论,并引用 Leland 的话:“实际上,“填充”实际上只是“间距”...所以如果负责 Compose 编译器/运行时的人这么说,我可以这么说;) 这个愚蠢的论点,因为边距是元素周围的空间,而填充是指元素与其内部内容之间的空间。一个可以贡献,即小部件可点击是,另一个不会。所以是的,从视觉上看,它可以被认为只是间距,但不同类型,因此 在功能上等效。 正如您在我上面的回答中看到的那样,第一个填充/间距就像一个边距。然后,我添加了边框和背景。然后我添加了另一个填充,它就像我们在当前 UI 框架上熟悉的填充一样。如果您在同一个示例中添加可点击修饰符,您会注意到背景/边框之外的区域不可点击。这就是为什么我说 padding 和 margin 是一回事,这取决于你在哪里使用它。 @MarcinOrlowski:“因为边距是元素周围的空间,而填充是指元素与其内部内容之间的空间”——在 Compose 中,实际上没有“元素”你的想法。 FWIW,this post 总结了 nglauber 所指的 Slack 线程,并提供了指向该线程的链接,如果您有兴趣阅读原始讨论。 我还是不明白。所以如果我有一个按钮,我想在其中添加边距。我只是添加填充吗?还是我做类似Container(modifier = Modifier.padding(16.dp) ) Button() ??【参考方案2】:

paddingmargin 的角度来看,你指的是我们习惯的所谓的box model。 Compose 中没有盒子模型,而是一系列应用于给定可组合项的修饰符。诀窍是您可以多次应用 padding 或 border 和 order of these matters 等相同的修饰符,例如:

@Composable
fun PaddingExample() 
    Text(
        text = "Hello World!",
        color = Color.White,
        modifier = Modifier
            .padding(8.dp) // margin
            .border(2.dp, Color.White) // outer border
            .padding(8.dp) // space between the borders
            .border(2.dp, Color.Green) // inner border
            .padding(8.dp) // padding
    )

结果你会得到这个可组合的:

这个设计在Modifiers documentation中有很好的解释:

注意:明确的顺序可以帮助您推断不同修饰符将如何交互。将此与您必须学习盒子模型的基于视图的系统进行比较,边距应用于元素“外部”但填充“内部”,并且背景元素将相应地调整大小。修饰符设计使这种行为明确且可预测,并为您提供更多控制权以实现您想要的确切行为。

【讨论】:

所以基本上它就像一个 Photoshop 图层和修改器是混合选项! 我仍然对修饰符有点困惑,感谢这个有趣的例子。我对此一无所知。【参考方案3】:

你也可以使用Spacer:

Spacer(modifier = Modifier.width(10.dp))

它代表一个空白的空间布局,其大小可以使用Modifier.widthModifier.heightModifier.size修饰符来定义。

假设你想在 2 个可组合项之间添加边距,那么你可以实现它

Text(
    text = stringResource(id = R.string.share_your_posters),
    fontSize = 16.sp,
    color = Color.Black
)

Spacer(modifier = Modifier.width(10.dp))

Image(painter = painterResource(id = R.drawable.ic_starts), contentDescription = null)

【讨论】:

【参考方案4】:

margin 与 padding 不同,margin 是小部件外部的空间,其中 padding 是小部件内部的距离,在旧的 XML 中你可以明确地决定使用哪一个,但是新的 compose 方式不同。

compose 如何处理内边距和边距?

有一个可以设置为参数的对象叫做Modifier,你可以用它来做边距和填充。

填充示例:

    Text(
    text = "Test",
    modifier = Modifier
        .padding(16.dp)
        .clickable  
)

保证金示例

    Text(
    text = "Test",
    modifier = Modifier
        .clickable  
        .padding(16.dp)
)

正如您在 compose 中看到的,这里的顺序有所不同,所有的修饰符都是按顺序实现的。

【讨论】:

【参考方案5】:

我也在寻找可以让我直接选择在 TextView 等视图上设置边距的东西。但不幸的是,我们在 Jetpack compose 中没有边距支持。但好消息是我们仍然可以通过使用像 Box 这样的布局容器来实现它,它允许我们添加像 TextView、ImageView 等视图。 因此,您可以通过对父级(Box)使用填充修饰符来为任何子级(TextView)添加边距。 代码如下:

Box(Modifier.padding(10.dp)) 
    Surface(color = Color.LightGray) 
        Text(text = "Hello $text!", color = Color.Blue,
            modifier = Modifier.padding(16.dp))
    

结果是:

这里我给了盒子 10.dp 的内边距。 希望有用。

【讨论】:

【参考方案6】:

因此,根据我在阅读文档后的理解,没有边距修饰符,因为 API 设计者认为给本质上做同样事情的不同名称是多余的。

假设您想在用黄色背景为容器着色之前应用 8dp 的边距,并且您希望容器的内容填充为 4dp。

Column(modifier = Modifier.padding(all = 8.dp)
                          .background(color = Color.Yellow)
                          .padding(all=4.dp)) 
        Text(text = "android")
        ...
    

在上面的示例中,您可以看到我首先应用了填充,然后我向容器添加了背景颜色,最后是最后一个填充。这就是它的外观。就像我们打算的那样。

【讨论】:

【参考方案7】:

您可以通过将具有填充的内容放入不同的可组合对象(如Box)和外部可组合对象clickable 来实现与边距相同的效果。通过这种方法,内部填充区域将包含在可点击内容中。

【讨论】:

以上是关于如何在 Jetpack Compose 中添加保证金?的主要内容,如果未能解决你的问题,请参考以下文章

将 jetpack compose 添加到现有项目

如何在jetpack compose中的网格项目之间添加空格

如何在 LazyColumn Jetpack Compose 中的项目之间添加分隔符?

Android:Activity 中的 Jetpack Compose 和 XML

如何在 Android Jetpack Compose 中结合使用 LazyColumn stickyHeader 和 Paging?

Jetpack Compose Text 超链接部分文本