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

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

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

请有人指导我。

非常感谢。

【问题讨论】:

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

标签: android android-jetpack-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 中没有盒子模型,而是一系列应用于给定可组合项的修饰符。诀窍是您可以多次应用 paddingborderorder 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 来实现与边距相同的效果。通过这种方法,内部填充区域将包含在可点击内容中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-10-25
            • 1970-01-01
            • 2020-05-30
            • 1970-01-01
            • 2023-01-07
            • 2022-11-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多