教程取自于Google官方课程之Kotlin 对 Jetpack Compose 的支持
Jetpack Compose 围绕 Kotlin 构建而成。在某些情况下,Kotlin 提供了一些特殊的惯用语,这使编写良好的 Compose 代码变得更容易。如果您用另一种编程语言思考,并在头脑中将这种语言翻译成 Kotlin,很可能会错失 Compose 的一些优势,还可能会发现很难理解以惯用语编写的 Kotlin 代码。进一步熟悉 Kotlin 的样式可帮助您避免这些隐患。
默认参数
编写 Kotlin 函数时,您可以指定函数参数的默认值;如果调用方未明确传递相应的值,系统就会使用这些默认值。此功能减少了对重载函数的需求。
例如,假设您要编写一个绘制正方形的函数。该函数可能有一个必需参数 sideLength,用于指定每条边的长度。它可能有几个可选参数,如 thickness、edgeColor 等;如果调用方未指定这些参数的值,该函数就会使用默认值。在其他语言中,您可能需要编写多个函数:
// We don't need to do this in Kotlin!
void drawSquare(int sideLength) {...}
void drawSquare(int sideLength, int thickness) {...}
void drawSquare(int sideLength, int thickness, Color edgeColor ) {...}
// …
在 Kotlin 中,您可以编写一个函数并指定参数的默认值:
fun drawSquare(
sideLength: Int,
thickness: Int = 2,
edgeColor: Color = Color.Black
) { ... }
高阶函数和 lambda 表达式
Kotlin 支持高阶函数,即接收其他函数作为参数的函数。Compose 在此方法的基础上构建而成。例如,Button
可组合函数提供了一个 onClick
lambda 参数。该参数的值是一个函数,当用户点击按钮时,按钮会调用该函数:
Button(
// ...
onClick = myClickFunction
)
高阶函数与 lambda 表达式(即求得的值是函数的表达式)自然配对。如果您只需要该函数一次,则不必在其他位置进行定义以将其传递给高阶函数,而只需使用 lambda 表达式在该位置定义该函数。前面的示例假设在其他位置定义了 myClickFunction()。但是,如果您只在此处使用该函数,则使用 lambda 表达式以内嵌方式定义该函数会更简单:
Button(
// ...
onClick = {
// do something
// do something else
}
) { /* ... */ }
尾随 lambda
Kotlin 提供了一种特殊语法来调用最后一个参数为 lambda 的高阶函数。如果您要将一个 lambda 表达式作为该参数传递,您可以使用尾随 lambda 语法。您应将 lambda 表达式放在圆括号后面,而不是将其放在圆括号内。这是 Compose 中的一种常见情况,因此您需要熟悉代码是什么样子的。
例如,所有布局的最后一个参数(如 Column()
可组合函数)均为 content
,它是一个发出子界面元素的函数。假设您想要创建一个包含三个文本元素的列,并且需要应用某种格式设置。以下代码行得通,但它非常繁琐:
Column(
modifier = Modifier.padding(16.dp),
content = {
Text("Some text")
Text("Some more text")
Text("Last text")
}
)
由于 content 参数是函数签名中的最后一个参数,并且我们要将其值作为 lambda 表达式传递,因此我们可以将其从圆括号中取出:
Column(modifier = Modifier.padding(16.dp)) {
Text("Some text")
Text("Some more text")
Text("Last text")
}
这两个示例的含义完全相同。大括号定义传递给 content 参数的 lambda 表达式。
事实上,如果您要传递的唯一一个参数是该尾随 lambda,也就是说,如果最后一个参数是 lambda,并且您不会传递其他任何参数,则您可以完全省略圆括号。例如,假设您不需要将修饰符传递给 Column。您可以像下面这样编写代码:
Column {
Text("Some text")
Text("Some more text")
Text("Last text")
}
此语法在 Compose 中十分常见,尤其是对于诸如 Column 之类的布局元素。最后一个参数是一个 lambda 表达式,它用于定义元素的子元素,这些子元素在函数调用后在大括号中指定。
网友评论