繁体   English   中英

Jetpack Compose - 修饰符顺序

[英]Jetpack Compose - Order of Modifiers

文档说修饰符是从左边应用的。 但是从这个例子来看,它们似乎是从右侧应用的:首先边框,然后填充,因为文本和边框之间没有空格

Text("Hi there!", Modifier.padding(10.dp).border(2.dp, Color.Magenta))

在此处输入图片说明

Jetpack Compose 代码实验室中有Layouts,其中包含解释修饰符顺序的Layout 修饰符,请参阅“顺序很重要”部分。

当链接修饰符时,顺序很重要,因为它们被应用到它们从早到晚修改的组合物,这意味着左侧修饰符的测量和布局将影响右侧的修饰符。 可组合的最终大小取决于作为参数传递的所有修饰符。 首先,修饰符将从左到右更新约束,然后,它们从右到左返回大小

为了更好地理解它,我建议弄清楚布局在 Compose 中是如何工作的。 简而言之, padding()是一个LayoutModifer ,它接受一些约束,根据该约束的投影测量其子级大小,并将子级放置在某些坐标处。

让我们看一个例子:

Box(
  modifier = Modifier
    .border(1.dp, Color.Red)
    .size(32.dp)
    .padding(8.dp)
    .border(1.dp, Color.Blue)
)

结果:

在此处输入图片说明

但是,让我们交换.size().padding()

Box(
  modifier = Modifier
    .border(1.dp, Color.Red)
    .padding(8.dp)
    .size(32.dp)
    .border(1.dp, Color.Blue)
)

现在我们有不同的结果:

在此处输入图片说明

我希望这个示例可以帮助您弄清楚如何应用修饰符。

可以预期,红色边框应该是最靠近框的,因为它是最先添加的,因此顺序可能看起来颠倒了,但这样的顺序也有优点。 让我们来看看这个可组合的:

@Composable
fun MyFancyButton(modifier: Modifier = Modifier) {
  Text(
    text = "Ok",
    modifier = modifier
      .clickable(onClick = { /*do something*/ })
      .background(Color.Blue, RoundedCornerShape(4.dp))
      .padding(8.dp)
  )
}

只需将modifier移动到参数,可组合项就允许其父项添加额外的修饰符,例如额外的边距。 因为最后添加的修饰符离按钮最近,所以边框和内边距不会受到影响。

  • 在 Android Compose 中,生成的 Image 是从外层向中心的 Composable 构建的。 这意味着首先定义的绿色边框是外边框,最后定义的红色边框是内边框。 这是非常令人困惑的,因为在代码中最接近文本可组合的绿色修饰符在结果中离它最远。
  • 这与 SwiftUI 形成对比,其中修饰符在代码和生成的图像中以相同的顺序出现。 在代码中最接近可组合的修饰符在结果图像中也最接近它。
  • 如果你想想象生成的图像是从你的 Composable 所在的中心构建的(就像在 SwiftUI 中一样),那么修饰符的应用顺序与它们给出的顺序相反(从底部向上)。
  • 因此,如果您有带有两个边框修饰符的 Text Composable
    • 代码中距离 Text Composable 最远的边框修饰符(底部红色)
    • 将最接近结果图像中的 Text Composable
  • 修饰符从外层向内层应用
    • 将 .border(2.dp, Color.Green) 应用到最外层
    • 向内应用 .padding(50.dp)
    • 将 .border(2.dp, Color.Red) 应用到最内层
package com.example.myapplication import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.* import androidx.compose.foundation.layout.padding import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.setContent import androidx.compose.ui.unit.dp class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text("Hi there!", Modifier .border(2.dp, Color.Green) .padding(50.dp) .border(2.dp, Color.Red) ) } } }

在此处输入图片说明

在这种情况下,第一个填充就像元素的边距。

比较这些可组合物,您会看到不同之处。

@Composable
fun Example() {
    // Default
    Box(modifier = Modifier.background(Color.Cyan), alignment = Alignment.Center){
        Text("Hi there!", Modifier.border(2.dp, Color.Magenta))
    }
    Divider()
    // 10dp margin
    Box(modifier = Modifier.background(Color.Cyan), alignment = Alignment.Center){
        Text("Hi there!", Modifier.padding(10.dp).border(2.dp, Color.Magenta))
    }
    Divider()
    // 10dp margin and 10dp padding
    Box(modifier = Modifier.background(Color.Cyan), alignment = Alignment.Center){
        Text("Hi there!", Modifier.padding(10.dp).border(2.dp, Color.Magenta).padding(10.dp))
    }
}

给定示例的渲染

“可以使用 then 组合修饰符元素。顺序很重要;首先出现的修饰符元素将首先应用。” @ 这里

它首先应用于外层,填充 10.dp,然后边框使用 color.Magenta,依此类推(“从左到右”)。 80.dp 填充最后应用于内层。

@Composable
fun test() {
    Text("Hi there!",
            Modifier.background(color = Color.Green)
                    .padding(10.dp)
                    .border(2.dp, Color.Magenta)
                    .padding(30.dp)
                    .border(2.dp, Color.Red)
                    .padding(80.dp)
    )
}

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM