将组件映射到现有代码

开发者可以通过提供界面软件包与现有代码组件之间的映射(而非生成的代码),自定义代码生成过程。如果现有实现具有生成的代码无法实现的功能,例如动画或复杂行为(如下拉菜单),这种做法会非常有用。

开发者指定如何使用映射文件映射组件。映射文件至少会告知代码生成器如何到达目标可组合函数,以便创建正确的客户端代码。

映射的组件概览图

示例如下:

在 Figma 中,设计人员创建了一个 Card 组件,其中包含 Play Bar 组件的一个实例,然后打包这两个组件并发送给开发者。

开发者从 Figma 导入界面软件包时,会在 ui-packages 中创建两个目录:cardplay_bar。在开发者构建项目时,系统会创建两个可组合函数:CardPlayBar。通常,由于 Card 包含 Figma 中的 Play Bar 实例,因此在代码中,Card 可组合函数包含对 PlayBar 可组合项的调用。

不过,设计人员和开发者希望 Card 改用现有的可组合项 MyExistingPlaybar,其具有在 Figma 中难以说明的功能。因此,开发者添加了一个名为 play_bar.json 的映射文件,用于将 play_bar 界面软件包映射到 MyExistingPlaybar

{
    "target": "MyExistingPlaybar",
    "package": "com.example.myApp"
}

现在,当开发者构建项目时,Card 会调用 MyExistingPlaybar,而不是 PlayBar。请注意,MyExistingPlaybar 的参数必须与 PlayBar 相同(但可以有一些差异,如下面的其他指令中所述)。

映射文件

在 Android Studio 项目中,映射文件会添加到 ui-packages 文件夹旁边的 ui-package-resources/mappings 下。Relay 会在构建期间查找映射文件。

项目视图中的映射文件

生成映射文件

Relay 可以为任何导入的界面软件包生成映射文件。请按以下步骤操作:

  1. 右键点击软件包文件夹或目标 ui-package 文件夹中的任何文件。选择生成映射文件

    生成映射文件可供性

  2. 在对话框中配置以下选项:

    用于生成映射文件的对话框

    • 文件位置:设置生成的映射文件的位置。

    • Target 可组合项:设置用于替代生成的可组合项的自定义可组合项。您可以选择使用现有的可组合项,也可以从对话框中创建新的可组合项。创建新的可组合项时,会创建一个采用界面软件包中定义的相同参数的可组合项。

    • Generated file:设置映射文件中的 generateImplementationgeneratePreview 选项。如需了解详情,请参阅下文的映射文件内容
  3. 点击生成映射文件。系统会使用指定配置在 ui-package-resources/mapping 文件夹内创建一个新的映射文件。

您还可以按照以下步骤从 Relay 软件包模块界面打开 Generate mapping file 对话框:

  1. 点击目标 ui-package 文件夹中的界面软件包的任意文件。

  2. 如果 Relay 工具窗口未自动打开,请点击 Relay 图标以打开窗口。

  3. 点击 Package Options 下的 Generate mapping file 按钮。

    生成映射文件可供性

映射文件名

给定映射文件的名称必须与其所替换组件的界面软件包文件夹的名称一致。因此,play_bar.json 会将 ui-packages/mappings 文件夹中的界面软件包映射到现有代码组件。

映射文件内容

映射文件包含以下属性:

  • target:(必需)自定义可组合函数的名称。默认情况下,这是由生成的代码创建的函数的名称。

    "target" : "CustomComposableName"
    
  • package:(必需)自定义可组合项所在的软件包的名称。默认情况下,这是由生成的代码创建的函数的软件包。

    "package" : "com.example.podcastapp.ui.components"
    
  • generateImplementation:(可选)true 或 false。如果为 true,系统仍会在生成的代码文件中创建此界面软件包的实现。如果为 false,则不会创建实现。默认为 true。

    "generateImplementation" : true
    
  • generatePreviews:(可选)true 或 false。如果为 true,则会在生成的代码文件中创建映射的自定义组件的预览。如果为 false,则不会创建预览。默认为 true。

    "generatePreviews" : true
    

映射的变体

如果 Figma 组件有变体,则生成的可组合项会包含对变体进行编码的枚举参数(如处理设计变体教程中所述)。如果您要将包含变体的 Figma 组件映射到现有代码,必须将其映射到与生成的可组合项采用相同参数的可组合项。例如,对于名为 Chip 的 Figma 组件,其变体的属性为 ChipType,Chip's 生成的可组合签名如下所示:

@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:将界面软件包字段映射到代码参数。
    • source:界面软件包中指定的参数名称。
    • target:目标代码组件中指定的参数名称。
  • lambda:将界面软件包字段映射到内容 lambda。
    • source:界面软件包中指定的参数名称。
    • target:目标代码组件中指定的参数名称。
  • modifier:将界面软件包字段映射到修饰符方法。

    • source:界面软件包中指定的参数名称。
    • method:应在生成的代码中调用的修饰符对象的方法。
    • parameter:指定的修饰符方法中的参数名称。
    • library:为访问修饰符方法而导入的限定软件包名称。
    • scope:表示修饰符范围的两个值之一:
    • any:该修饰符可以在任何接收器范围内使用。
    • relay:该修饰符必须在 Relay 的 RelayContainer 对象的接收器范围内使用。