开发者可以通过提供 UI 包和现有代码组件之间的映射来自定义代码生成过程,而不是使用生成的代码。当现有实现具有生成的代码无法实现的功能(例如动画或复杂行为(例如下拉菜单))时,这非常有用。
开发者使用映射文件指定如何映射组件。映射文件至少告诉代码生成器如何访问目标可组合函数,以便可以创建正确的客户端代码。
这是一个示例
在 Figma 中,设计师创建一个 **卡片** 组件,该组件包含一个 **播放栏** 组件的实例,打包这两个组件,然后将它们发送给开发者。
当开发者从 Figma 导入 UI 包时,会在 ui-packages 中创建两个目录:card 和 play_bar。当他们构建项目时,会创建两个可组合函数:Card 和 PlayBar。通常,因为 **卡片** 在 Figma 中包含 **播放栏** 实例,所以在代码中,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** 且其属性为 **ChipType** 的 Figma 组件,**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对象的接收器作用域中使用。