开发者可以通过提供 UI 包和现有代码组件之间的映射来定制代码生成过程,而不是生成代码。当现有实现具有无法通过生成的代码实现的功能(例如动画或复杂行为(例如下拉菜单))时,这将非常有用。
开发者使用映射文件来指定如何映射组件。映射文件至少告诉代码生成器如何到达目标可组合函数,以便可以创建正确的客户端代码。
以下是一个示例
在 Figma 中,设计师创建了一个 **Card** 组件,该组件 包含一个 **Play Bar** 组件的实例,将这两个组件打包并发送给开发者。
当开发者从 Figma 导入 UI 包时,将在 ui-packages
中创建两个目录:card
和 play_bar
。当他们构建项目时,会创建两个可组合函数:Card
和 PlayBar
。通常,因为 **Card** 在 Figma 中包含一个 **Play Bar** 实例,所以在代码中 Card
可组合函数包含对 PlayBar
可组合函数的调用。
但是,设计师和开发者希望 Card
改用现有可组合函数 MyExistingPlaybar
,该函数具有难以在 Figma 中描述的功能。因此,开发者添加了一个名为 play_bar.json
的映射文件,该文件将 play_bar
UI 包映射到 MyExistingPlaybar
{
"target": "MyExistingPlaybar",
"package": "com.example.myApp"
}
现在,当开发者构建项目时,Card
会调用 MyExistingPlaybar
而不是 PlayBar
。请注意,MyExistingPlaybar
必须具有与 PlayBar
相同的参数(尽管可能存在一些差异,如下面的 其他指令 中所述)。
映射文件
在您的 Android Studio 项目中,映射文件被添加到 ui-package-resources/mappings
下,位于 ui-packages
文件夹旁边。Relay 在构建期间查找映射文件。
生成映射文件
Relay 可以为任何导入的 UI 包生成映射文件。请按照以下步骤操作
右键单击目标
ui-package
文件夹中的包文件夹或任何文件。选择 **生成映射文件**。在对话框中配置以下选项
**文件位置:** 设置生成的映射文件的位置。
**目标可组合函数:** 设置用于代替生成的可组合函数的自定义可组合函数。您可以选择使用现有可组合函数或从对话框中创建新的可组合函数。创建新的可组合函数会在 UI 包中定义的参数的基础上创建一个可组合函数。
- **生成的文件:** 在映射文件中设置
generateImplementation
和generatePreview
选项。有关详细信息,请参见下面的 映射文件内容。
单击 **生成映射文件**。一个新的映射文件将在
ui-package-resources/mapping
文件夹中创建,其中包含指定的配置。
您也可以使用以下步骤从 Relay 包模块 UI 中打开 **生成映射文件** 对话框
单击目标
ui-package
文件夹中的 UI 包的任何文件。如果 Relay 工具窗口没有自动打开,请单击 Relay 图标以打开窗口。
单击 **包选项** 下的 **生成映射文件** 按钮。
映射文件名
给定映射文件的名称必须与它替换的组件的 UI 包文件夹的名称匹配。因此,play_bar.json
将 ui-packages/mappings
文件夹中的 UI 包映射到现有代码组件。
映射文件内容
映射文件包含以下属性
**target:** (必需)自定义可组合函数的名称。默认情况下,此名称是生成代码创建的函数的名称。
"target" : "CustomComposableName"
**package:** (必需)自定义可组合函数所在的包的名称。默认情况下,此名称是生成代码创建的函数的包的名称。
"package" : "com.example.podcastapp.ui.components"
**generateImplementation:** (可选)true 或 false。如果为 true,则在生成的代码文件中仍然会创建此 UI 包的实现。如果为 false,则不会创建实现。默认情况下,此值为 true。
"generateImplementation" : true
**generatePreviews:** (可选)true 或 false。如果为 true,则会在生成的代码文件中创建映射的自定义组件的预览。如果为 false,则不会创建预览。默认情况下,此值为 true。
"generatePreviews" : true
映射的变体
如果 Figma 组件具有变体,则生成的可组合函数包含枚举参数,这些参数对变体进行编码(如 处理设计变体 教程中所述)。如果您要将具有变体的 Figma 组件映射到现有代码,则必须将其映射到与生成的可组合函数采用相同参数的可组合函数。例如,对于名为 **Chip** 的 Figma 组件,其变体的属性为 **ChipType,Chip** 的生成的可组合函数签名如下所示
@Composable
fun Chip(
modifier: Modifier = Modifier,
chipType: ChipType = ChipType.Red,
chipText: String
) { ... }
如果您希望 Chip Figma 组件映射到现有的 MyChip
可组合函数,则 MyChip
的签名必须与生成的可组合函数的签名相同(假设没有指定 其他指令)。从概念上讲,这表明现有代码组件能够与 Figma 组件具有相同的设计变体。
其他指令
例如,如果您要定位的可组合函数具有以下签名
@Composable
fun MyChip(
modifier: Modifier = Modifier,
chipType: ChipType = ChipType.Red,
description: String // instead of chipText
) { ... }
您可以将 fieldMappings
块添加到映射文件中,以影响参数的映射方式。在本例中,它包含从 Chip
中的 chipText
参数到 MyChip
中的 description
参数的映射。
{
"target": "MyChip",
"package": "com.example.myApp",
"fieldMappings": [
{
"type": "parameter",
"source": "chipText",
"target": "description"
}
]
}
fieldMappings
块的类型包括
parameter
:将 UI 包字段映射到代码参数。source
:UI 包中指定的参数的名称。target
:目标代码组件中指定的参数的名称。
lambda
:将 UI 包字段映射到内容 lambda。source
:UI 包中指定的参数的名称。target
:目标代码组件中指定的参数的名称。
modifier
:将 UI 包字段映射到 修饰符 方法。source
:UI 包中指定的参数的名称。method
:在 Modifier 对象上应在生成的代码中调用的方法。parameter
:指定 Modifier 方法中的参数的名称。library
:用于访问 Modifier 方法的限定包名称。scope
:两个值之一,用于指示 Modifier 的作用域any
:修饰符可以在任何接收器作用域中使用。relay
:修饰符必须在 Relay 的RelayContainer
对象的接收器作用域中使用。